//! Nsb.debug.js
//

(function() {

////////////////////////////////////////////////////////////////////////////////
// ExpandoPlugin

jQuery.fn.expando = function ExpandoPlugin$expando(customOptions) {
    /// <param name="customOptions" type="Object">
    /// </param>
    /// <returns type="jQueryObject"></returns>
    var leftMark = '&#x25C4;';
    var rightMark = '&#x25BA;';
    var downMark = '&#x25BC;';
    var eMarkClass = 'expandoPluginMark';
    var defaultOptions = { side: 'left', initiallyClosed: true, fullSurface: false };
    var options = $.extend({}, defaultOptions, customOptions);
    if (ss.isNullOrUndefined(options.openMark)) {
        options.openMark = downMark;
    }
    if (ss.isNullOrUndefined(options.closedMark)) {
        options.closedMark = (options.side === 'left') ? rightMark : leftMark;
    }
    return this.each(function(i, element) {
        var expando = $('<span/>').css({ color: '#008', padding: ((options.side === 'left') ? '0 5px 0 0' : '0 0 0 5px') }).addClass(eMarkClass).html((options.initiallyClosed) ? options.closedMark : options.openMark);
        options.clickOpen = function(e) {
            $(this).unbind('click').click(options.clickClosed).closest('dl').children('dd').show();
            $(this).parent().find('.' + eMarkClass).html(options.openMark);
            e.stopImmediatePropagation();
            e.preventDefault();
        };
        options.clickClosed = function(e) {
            $(this).unbind('click').click(options.clickOpen).closest('dl').children('dd').hide();
            $(this).parent().find('.' + eMarkClass).html(options.closedMark);
            e.stopImmediatePropagation();
            e.preventDefault();
        };
        if (options.side === 'left') {
            expando.prependTo($(this).children('dt'));
        }
        else {
            expando.appendTo($(this).children('dt'));
        }
        ((options.fullSurface) ? expando.parent() : expando).click(function(e) {
            var dd = $(this).closest('dt').next('dd');
            if (dd.is(':visible')) {
                (options.clickClosed).call(this, e);
            }
            else {
                (options.clickOpen).call(this, e);
            }
        }).css('cursor', 'pointer');
        if (options.initiallyClosed) {
            $(this).children('dd').hide();
        }
        else {
            $(this).children('dd').show();
        }
    });
}


////////////////////////////////////////////////////////////////////////////////
// jQueryJewlExtensions

jQuery.fn.endEvent = function jQueryJewlExtensions$endEvent(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    /// <returns type="jQueryObject"></returns>
    DomElement.cancelEvent(e);
    return this;
}
jQuery.fn.fValueString = function jQueryJewlExtensions$fValueString(txt) {
    /// <param name="txt" type="String">
    /// </param>
    /// <returns type="jQueryObject"></returns>
    txt = txt.replace(DomElement.regMe('/&nbsp;/g'), ' ');
    txt = txt.replace(DomElement.regMe('/<br>/g'), '\n');
    txt = txt.replace(DomElement.regMe('/&lt;/g'), '<');
    txt = txt.replace(DomElement.regMe('/&gt;/g'), '>');
    txt = txt.replace(DomElement.regMe('/&amp;/g'), '&');
    if (this.is('input[type=text],textarea,select')) {
        return this.val(txt);
    }
    if (this.is('input[type=checkbox]')) {
        if (Boolean.parse(txt)) {
            return this.attr('checked', 'checked');
        }
        return this.removeAttr('checked');
    }
    return this.html(txt);
}
jQuery.fn.fValue = function jQueryJewlExtensions$fValue(dta) {
    /// <param name="dta" type="Object">
    /// </param>
    /// <returns type="jQueryObject"></returns>
    if (this.is('input[type=checkbox]')) {
        if (dta) {
            return this.attr('checked', 'checked');
        }
        return this.removeAttr('checked');
    }
    dta = (dta == null) ? '' : dta.toString();
    return this.fValueString(dta);
}
jQuery.fn.getFValue = function jQueryJewlExtensions$getFValue() {
    /// <returns type="Object"></returns>
    var txt;
    if (this.is('input[type=text],textarea,select')) {
        txt = this.val();
    }
    else if (this.is('input[type=checkbox]')) {
        return this.is(':checked');
    }
    else {
        return this.html();
    }
    txt = txt.trim();
    txt = txt.replace(DomElement.regMe('/<[^0-9\\s].*?>/g'), '');
    txt = txt.replace(DomElement.regMe('/</g'), '&lt;');
    txt = txt.replace(DomElement.regMe('/>/g'), '&gt;');
    txt = txt.replace(DomElement.regMe('/\\r/g'), '');
    txt = txt.replace(DomElement.regMe('/\\n/g'), '<br>');
    txt = txt.replace(DomElement.regMe('/\\s\\s/g'), '&nbsp;&nbsp;');
    txt = txt.replace(DomElement.regMe('/&([^a-z#0-9]+?[^;])/g'), '&amp;$1');
    return txt.trim();
}
jQuery.fn.getFValueString = function jQueryJewlExtensions$getFValueString() {
    /// <returns type="String"></returns>
    return this.getFValue().toString();
}
jQuery.fn.getFEditString = function jQueryJewlExtensions$getFEditString() {
    /// <returns type="String"></returns>
    var txt1 = this.val();
    var txt2 = this.getFValue().toString();
    if (Rx.hasEndSpace.test(txt1)) {
        txt2 += ' ';
    }
    return txt2;
}
jQuery.fn.swallowAllMouseEvents = function jQueryJewlExtensions$swallowAllMouseEvents() {
    /// <returns type="jQueryObject"></returns>
    return this.click(function(e) {
        DomElement.cancelEvent(e);
    }).dblclick(function(e) {
        DomElement.cancelEvent(e);
    }).mousedown(function(e) {
        DomElement.cancelEvent(e);
    }).mouseup(function(e) {
        DomElement.cancelEvent(e);
    }).mouseover(function(e) {
        DomElement.cancelEvent(e);
    }).mouseenter(function(e) {
        DomElement.cancelEvent(e);
    }).mouseleave(function(e) {
        DomElement.cancelEvent(e);
    });
}
jQuery.fn.swallowClick = function jQueryJewlExtensions$swallowClick(fn) {
    /// <param name="fn" type="Function">
    /// </param>
    /// <returns type="jQueryObject"></returns>
    return this.click(fn).mousedown(DomElement.cancelEvent).dblclick(DomElement.cancelEvent).mouseup(DomElement.cancelEvent);
}
jQuery.fn.vertHtml = function jQueryJewlExtensions$vertHtml() {
    /// <returns type="jQueryObject"></returns>
    var value = this.getFValueString();
    var f = $('<p/>').html(value);
    return this.fValueString(f.html());
}
jQuery.fn.fitIntoWindow = function jQueryJewlExtensions$fitIntoWindow() {
    /// <returns type="jQueryObject"></returns>
    var sctop = $(window.document).scrollTop();
    var scleft = $(window.document).scrollLeft();
    var top = this.offset().top;
    var left = this.offset().left;
    top = Math.max(top, sctop);
    left = Math.max(left, scleft);
    top = Math.min(top, sctop + $(window.self).innerHeight() - this.outerHeight());
    left = Math.min(left, scleft + $(window.self).innerWidth() - this.outerWidth());
    this.css('top', top + 'px');
    return this.css('left', left + 'px');
}
jQuery.fn.cloneToBody = function jQueryJewlExtensions$cloneToBody(element) {
    /// <param name="element" type="jQueryObject">
    /// </param>
    /// <returns type="jQueryObject"></returns>
    var ths = this;
    var el = $("<div class='GigMu MenuZee'/>").appendTo(document.body).offset(element.offset());
    ths.appendTo(el).show();
    if (ths.data('GigMu1') == null) {
        ths.bind('mouseleave.Gears', function() {
            ths.detach();
            var fnOff = ths.data('GearsOff');
            if (fnOff != null) {
                fnOff();
            }
            el.remove();
        });
    }
    ths.data('GigMu1', ths);
    ths.data('GigMu2', el);
    return ths;
}
jQuery.fn.getSelection = function jQueryJewlExtensions$getSelection() {
    /// <returns type="Object"></returns>
    var el = this[0];
    var start = 0;
    var end = 0;
    if (typeof el.selectionStart == 'number' && typeof el.selectionEnd == 'number') {
        start = el.selectionStart;
        end = el.selectionEnd;
    }
    else {
        var range = document.selection.createRange();
        if (!!range && range.parentElement() == el) {
            var len = el.value.length;
            var normalizedValue = el.value.replace(/\r\n/g, '\n');
            var textInputRange = el.createTextRange();
            textInputRange.moveToBookmark(range.getBookmark());
            var endRange = el.createTextRange();
            endRange.collapse(false);
            if (textInputRange.compareEndPoints('StartToEnd', endRange) > -1) {
                start = end = len;
            }
            else {
                start = -textInputRange.moveStart('character', -len);
                start += normalizedValue.slice(0, start).split('\n').length - 1;
                if (textInputRange.compareEndPoints('EndToEnd', endRange) > -1) {
                    end = len;
                }
                else {
                    end = -textInputRange.moveEnd('character', -len);
                    end += normalizedValue.slice(0, end).split('\n').length - 1;
                }
            }
        }
    }
    return { start: start, end: end };
}
jQuery.fn.cloneEditCSS = function jQueryJewlExtensions$cloneEditCSS() {
    /// <returns type="Object"></returns>
    var el = this;
    var p = el.offset();
    return { position: 'absolute', margin: 0, top: p.top, left: p.left, width: el.innerWidth(), height: el.innerHeight(), border: 'none', background: '#FFC', 'font-family': el.css('font-family'), 'font-size': el.css('font-size'), 'font-weight': el.css('font-weight'), 'text-decoration': el.css('text-decoration'), 'padding-top': el.css('padding-top'), 'padding-left': el.css('padding-left'), 'padding-right': el.css('padding-right'), 'padding-bottom': el.css('padding-bottom'), overflow: 'hidden' };
}
jQuery.fn.fadeInW = function jQueryJewlExtensions$fadeInW(ms, fn) {
    /// <param name="ms" type="Number" integer="true">
    /// </param>
    /// <param name="fn" type="Function">
    /// </param>
    /// <returns type="jQueryObject"></returns>
    FileBlobBase.svCnt++;
    return this.fadeIn(ms, function() {
        if (fn != null) {
            fn();
        }
        FileBlobBase.svCnt--;
    });
}
jQuery.fn.fadeOutW = function jQueryJewlExtensions$fadeOutW(ms, fn) {
    /// <param name="ms" type="Number" integer="true">
    /// </param>
    /// <param name="fn" type="Function">
    /// </param>
    /// <returns type="jQueryObject"></returns>
    FileBlobBase.svCnt++;
    return this.fadeOut(ms, function() {
        if (fn != null) {
            fn();
        }
        FileBlobBase.svCnt--;
    });
}
jQuery.fn.info = function jQueryJewlExtensions$info(msg) {
    /// <param name="msg" type="String">
    /// </param>
    /// <returns type="jQueryObject"></returns>
    Inform.log('Jewl.Inform: ' + msg);
    return this;
}


Type.registerNamespace('Nsb');

////////////////////////////////////////////////////////////////////////////////
// Nsb._awaitClassTests

Nsb._awaitClassTests = function Nsb__awaitClassTests() {
    Nsb._awaitClassTests.initializeBase(this);
}
Nsb._awaitClassTests.prototype = {
    
    testMethod1: function Nsb__awaitClassTests$testMethod1() {
        QUnit.expect(2);
        QUnit.ok(true, 'Hello');
        var cc = 0;
        var awx = new Await().que(function(aw) {
            window.setTimeout(function() {
                QUnit.ok(false, 'Await 1');
                Inform.log('Await 1');
                aw.set_item('aw1', '1');
                aw.done();
            }, 200);
        }).que(function(aw) {
            Inform.log('Await 2');
            aw.doneWith('aw2', '2');
        }).addDl(function(aw) {
            window.setTimeout(function() {
                Inform.log('Await 3');
                aw.doneWith('aw3', '3');
            }, 200);
        }).addDl(function(aw) {
            Inform.log('Await 4 throw');
            aw.set_item('aw4', '4');
            if (aw.get_item('aw4') === '4') {
                throw new Error('xxx exception');
            }
            aw.done();
        }).handleDl('xxx exception', function(aw) {
            Inform.log('Await handler');
            aw.set_item('aw4', 'thrown');
        }).addDl(function(aw) {
            Inform.log('Await 5');
            aw.doneWith('aw5', '5');
        }).addDx(function(aw) {
            Inform.log('Await Deferred {0}, {1}, {2}, {3}', aw.get_item('aw1'), aw.get_item('aw2'), aw.get_item('aw3'), aw.get_item('aw4'));
            Inform.log('.............. {0}', aw.get_item('aw5'));
            if (!cc++) {
                aw.commit();
            }
        }).commit();
    },
    
    testMethod2: function Nsb__awaitClassTests$testMethod2() {
        QUnit.stop();
    }
}


////////////////////////////////////////////////////////////////////////////////
// DynamicCss

DynamicCss = function DynamicCss() {
}
DynamicCss.addCssRule = function DynamicCss$addCssRule(ruleName, rules) {
    /// <summary>
    /// Adds the CSS rule to the DOM.
    /// Use DynamicCss.AddCssRule(ruleName, ruleDictionary).
    /// </summary>
    /// <param name="ruleName" type="String">
    /// Name of the rule in CSS standard format.
    /// </param>
    /// <param name="rules" type="Object">
    /// Dictionary of the rules to add.
    /// </param>
    /// <returns type="Object" domElement="true"></returns>
    var dataname = 'AddCssRuleData';
    var jq = window.self.jQuery;
    var data = jq[dataname];
    if (typeof(data) === 'undefined') {
        data = {};
        data.sheetName = 'DynamicCss-StyleSheet';
        data.undefined_as_dictionary = undefined;
        jq[dataname] = data;
        var cssNode = document.createElement('style');
        cssNode.id = new Date().getTime().toString();
        cssNode.type = 'text/css';
        cssNode.rel = 'stylesheet';
        cssNode.media = 'screen';
        cssNode.title = data.sheetName;
        document.getElementsByTagName('head')[0].appendChild(cssNode);
    }
    if (('styleSheets' in window.document)) {
        if (typeof(rules) === 'undefined') {
            var stylesheets = window.document.styleSheets;
            for (var j = 0; j < stylesheets.length; j++) {
                var ru = null;
                try {
                    var sth = stylesheets[j];
                    if (sth.title !== data.sheetName) {
                        continue;
                    }
                    if ((typeof(sth.insertRule) === 'function')) {
                        var ix = sth.insertRule(ruleName + ' { }', 0);
                        ru = sth.cssRules[ix];
                    }
                    else if ((typeof(sth.addRule) === 'function')) {
                        sth.addRule(ruleName, null, 0);
                        ru = sth.rules[0];
                    }
                    else {
                        throw new Error('CANT FIND insertRule OR SIMILAR CSS FUNCTION');
                    }
                }
                catch ($e1) {
                }
                return ru;
            }
            throw new Error('FAILED TO ADD CSS RULE or NO DynamicCss SHEET');
        }
        $(DynamicCss.addCssRule(ruleName, data.undefined_as_dictionary)).css(rules);
        return null;
    }
    throw new Error('NO BROWSER DYNAMIC STYLESHEET SUPORT');
}


////////////////////////////////////////////////////////////////////////////////
// Nsb.Encoder

Nsb.Encoder = function Nsb_Encoder() {
}
Nsb.Encoder.lzwEncode = function Nsb_Encoder$lzwEncode(s) {
    /// <param name="s" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return Encoder.LzwEncode(s);
}
Nsb.Encoder.lzwDecode = function Nsb_Encoder$lzwDecode(s) {
    /// <param name="s" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return Encoder.LzwDecode(s);
}
Nsb.Encoder.encode64 = function Nsb_Encoder$encode64(s) {
    /// <param name="s" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return Encoder.Encode64(s);
}
Nsb.Encoder.decode64 = function Nsb_Encoder$decode64(s) {
    /// <param name="s" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return Encoder.Decode64(s);
}


////////////////////////////////////////////////////////////////////////////////
// Nsb.Storage

Nsb.Storage = function Nsb_Storage() {
}
Nsb.Storage.setLocal = function Nsb_Storage$setLocal(n, v) {
    /// <param name="n" type="String">
    /// </param>
    /// <param name="v" type="Object">
    /// </param>
    Nsb.Storage._dbPackage(n, v, window.localStorage);
}
Nsb.Storage.setSession = function Nsb_Storage$setSession(n, v) {
    /// <param name="n" type="String">
    /// </param>
    /// <param name="v" type="Object">
    /// </param>
    Nsb.Storage._dbPackage(n, v, window.sessionStorage);
}
Nsb.Storage.getLocal = function Nsb_Storage$getLocal(n) {
    /// <param name="n" type="String">
    /// </param>
    /// <returns type="Object"></returns>
    return Nsb.Storage._dbUnpackage(n, window.localStorage);
}
Nsb.Storage.getSession = function Nsb_Storage$getSession(n) {
    /// <param name="n" type="String">
    /// </param>
    /// <returns type="Object"></returns>
    return Nsb.Storage._dbUnpackage(n, window.sessionStorage);
}
Nsb.Storage.removeLocal = function Nsb_Storage$removeLocal(n) {
    /// <param name="n" type="String">
    /// </param>
    try {
        window.localStorage.removeItem(n);
    }
    catch ($e1) {
        window.localStorage[n] = '';
    }
}
Nsb.Storage.removeSession = function Nsb_Storage$removeSession(n) {
    /// <param name="n" type="String">
    /// </param>
    try {
        window.sessionStorage.removeItem(n);
    }
    catch ($e1) {
        window.sessionStorage[n] = '';
    }
}
Nsb.Storage.compareLocal = function Nsb_Storage$compareLocal(n, v) {
    /// <param name="n" type="String">
    /// </param>
    /// <param name="v" type="Object">
    /// </param>
    /// <returns type="Boolean"></returns>
    return Nsb.Storage.compareObjects(Nsb.Storage._dbUnpackage(n, window.localStorage), v);
}
Nsb.Storage.compareObjects = function Nsb_Storage$compareObjects(a, b) {
    /// <param name="a" type="Object">
    /// </param>
    /// <param name="b" type="Object">
    /// </param>
    /// <returns type="Boolean"></returns>
    if (ss.isNullOrUndefined(a) || ss.isNullOrUndefined(b)) {
        return false;
    }
    return JSON.stringify(a) === JSON.stringify(b);
}
Nsb.Storage._dbPackage = function Nsb_Storage$_dbPackage(n, v, store) {
    /// <param name="n" type="String">
    /// </param>
    /// <param name="v" type="Object">
    /// </param>
    /// <param name="store" type="Storage">
    /// </param>
    switch (typeof(v)) {
        case 'object':
            v = '@@object@@' + Nsb.Storage.ultraStringify(v);
            break;
        default:
            v = v.toString();
            break;
    }
    store.setItem(n, v);
}
Nsb.Storage._dbUnpackage = function Nsb_Storage$_dbUnpackage(n, store) {
    /// <param name="n" type="String">
    /// </param>
    /// <param name="store" type="Storage">
    /// </param>
    /// <returns type="Object"></returns>
    var v = store.getItem(n);
    if (ss.isNull(v)) {
        return undefined;
    }
    if (new RegExp('^@@object@@').test(v)) {
        try {
            return eval('(' + v.substr(10) + ')');
        }
        catch (ex) {
            Inform.log('Syntax error parsing stored "' + n + '" object: ' + ex);
        }
        return undefined;
    }
    return Nsb.Storage.stringValue(v);
}
Nsb.Storage.stringValue = function Nsb_Storage$stringValue(v) {
    /// <param name="v" type="String">
    /// </param>
    /// <returns type="Object"></returns>
    switch (v) {
        case 'true':
            return true;
        case 'false':
            return false;
        case 'null':
            return null;
        case 'undefined':
            return undefined;
    }
    return v;
}
Nsb.Storage.ultraStringify = function Nsb_Storage$ultraStringify(item) {
    /// <param name="item" type="Object">
    /// </param>
    /// <returns type="Object"></returns>
    return JSON.stringify(item, function(n, v) {
        return (typeof(v) === 'function') ? v.toString() : v;
    });
}


////////////////////////////////////////////////////////////////////////////////
// Transform

Transform = function Transform() {
}
Transform.htmlize = function Transform$htmlize(txt, pass) {
    /// <param name="txt" type="String">
    /// </param>
    /// <param name="pass" type="Boolean">
    /// </param>
    /// <returns type="String"></returns>
    if (pass) {
        return txt;
    }
    var ot = '';
    var c;
    for (var i = 0; i < txt.length; i++) {
        c = txt.substr(i, 1);
        switch (c) {
            case '<':
                ot += '&lt;';
                break;
            case '>':
                ot += '&gt;';
                break;
            case '&':
                ot += '&amp;';
                break;
            case '\n':
                ot += '<br/>';
                break;
            case ' ':
                ot += '&nbsp;';
                break;
            default:
                ot += c;
                break;
        }
    }
    return ot;
}


Type.registerNamespace('Nsb.Classes');

////////////////////////////////////////////////////////////////////////////////
// Actor

Actor = function Actor() {
    /// <field name="acting" type="Boolean">
    /// </field>
    /// <field name="fadeIn" type="Number" integer="true">
    /// </field>
    /// <field name="fadeOut" type="Number" integer="true">
    /// </field>
    /// <field name="followDelegate" type="Function">
    /// </field>
    /// <field name="followTmr" type="Number" integer="true">
    /// </field>
    /// <field name="waitTmr" type="Number" integer="true">
    /// </field>
    /// <field name="isFollowable" type="Boolean">
    /// </field>
    /// <field name="mouseX" type="Number" integer="true">
    /// </field>
    /// <field name="mouseY" type="Number" integer="true">
    /// </field>
    /// <field name="trackingDone" type="Boolean">
    /// </field>
    /// <field name="_frames$2" type="Array">
    /// </field>
    this._frames$2 = [];
    Actor.initializeBase(this);
}
Actor._shaker$2 = function Actor$_shaker$2(x, t, b, c, d) {
    /// <param name="x" type="Number" integer="true">
    /// </param>
    /// <param name="t" type="Number" integer="true">
    /// </param>
    /// <param name="b" type="Number" integer="true">
    /// </param>
    /// <param name="c" type="Number" integer="true">
    /// </param>
    /// <param name="d" type="Number" integer="true">
    /// </param>
    /// <returns type="Number"></returns>
    return c * Math.sin(t / d * 3 * 4 * (Math.PI / 2)) + b;
}
Actor.prototype = {
    acting: false,
    fadeIn: 200,
    fadeOut: 200,
    followDelegate: null,
    followTmr: 0,
    waitTmr: 0,
    isFollowable: true,
    mouseX: 0,
    mouseY: 0,
    trackingDone: false,
    
    followMouse: function Actor$followMouse() {
        /// <returns type="Actor"></returns>
        this.unfollowMouse();
        this.followDelegate = ss.Delegate.create(this, function(e) {
            this.mouseY = e.pageY;
            this.mouseX = e.pageX;
        });
        $(window.self).bind('mousemove.actor', this.followDelegate);
        this._followable$2();
        this.startActing();
        return this;
    },
    
    unfollowMouse: function Actor$unfollowMouse() {
        /// <returns type="Actor"></returns>
        this.resetTimers();
        if (this.followDelegate != null) {
            this.followDelegate = null;
            $(window.self).unbind('mousemove.actor');
        }
        return this;
    },
    
    recordFrame: function Actor$recordFrame() {
        var aa = $.extend(new Actor(), this);
        aa.element = this.element.clone(true, true);
        this._frames$2.add(aa);
    },
    
    rewindTo: function Actor$rewindTo(idx) {
        /// <param name="idx" type="Number" integer="true">
        /// </param>
        /// <returns type="Actor"></returns>
        var aa = this._frames$2[idx];
        if (aa != null) {
            var pr = this.element;
            var el = aa.element.clone(true, true);
            this.element.replaceWith(el);
            this.element = el;
            var $dict1 = Cluster.elements;
            for (var $key2 in $dict1) {
                var p = { key: $key2, value: $dict1[$key2] };
                if (p.value === pr) {
                    Cluster.elements[p.key] = el;
                }
            }
        }
        return this;
    },
    
    shake: function Actor$shake(ms) {
        /// <param name="ms" type="Number" integer="true">
        /// </param>
        /// <returns type="Actor"></returns>
        if (this.acting) {
            return this;
        }
        this.acting = true;
        ms = (ms || 200);
        jQuery.easing.shaker = Actor._shaker$2;
        var p = this.element.position();
        this.element.css(p);
        var props = { top: p.top + 5 + 'px', left: p.left + 5 + 'px' };
        var opts = { duration: ms, easing: 'shaker', complete: ss.Delegate.create(this, function() {
            this.element.css(p);
        }) };
        new Await().addAw(ss.Delegate.create(this, this.animateAw), props, opts).addDx(ss.Delegate.create(this, function() {
            this.acting = false;
        })).commit();
        return this;
    },
    
    animateAw: function Actor$animateAw(awp, props, opts) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="props" type="Object">
        /// </param>
        /// <param name="opts" type="Object">
        /// </param>
        var op = (opts || {});
        var pp = (props || {});
        var cp = (op['complete'] || function() {
        });
        op['complete'] = function() {
            cp();
            awp.done();
        };
        this.element.animate(pp, op);
    },
    
    slideInAw: function Actor$slideInAw(awp, el) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="el" type="jQueryObject">
        /// </param>
        el = el || this.element;
        if (el != null) {
            var lf = Math.max(el.position().left, parseInt(el.css('left')));
            el.show().css({ left: (Math.min(10, lf - 150) + 'px'), visibility: 'visible' }).animate({ left: lf + 'px' }, 150, 'swing', function() {
                awp.done();
            });
        }
    },
    
    resetTimers: function Actor$resetTimers() {
        window.clearTimeout(this.followTmr);
        window.clearTimeout(this.waitTmr);
        this.followTmr = this.waitTmr = 0;
    },
    
    _followable$2: function Actor$_followable$2() {
        this.isFollowable = true;
    },
    
    startActing: function Actor$startActing() {
        this.acting = true;
        this.trackingDone = false;
        window.clearTimeout(this.followTmr);
        this.followTmr = window.setTimeout(ss.Delegate.create(this, this.follow), 1);
        this.element.fadeIn(this.fadeIn);
    },
    
    follow: function Actor$follow() {
        this.element.css('top', this.mouseY + 'px').css('left', this.mouseX + 'px');
        window.clearTimeout(this.followTmr);
        this.followTmr = window.setTimeout(ss.Delegate.create(this, this.follow), 30);
    },
    
    waitTrackingDoneAw: function Actor$waitTrackingDoneAw(awp) {
        /// <param name="awp" type="Await">
        /// </param>
        if (!this.trackingDone) {
            window.clearTimeout(this.waitTmr);
            this.waitTmr = window.setTimeout(ss.Delegate.create(this, function() {
                this.waitTrackingDoneAw(awp);
            }), 13);
            return;
        }
        awp.done();
    },
    
    viewit: function Actor$viewit(url) {
        /// <param name="url" type="String">
        /// </param>
        /// <returns type="Actor"></returns>
        return new Actor().fromHtml('<div/>').html("<iframe src='" + url + '&output=embed' + "' frameborder='0' width='480' height='389' allowfullscreen='false' webkitallowfullscreen='false'></iframe>").appendTo(this.element);
    },
    
    html: function Actor$html(html) {
        /// <param name="html" type="String">
        /// </param>
        /// <returns type="Actor"></returns>
        return Actor.callBaseMethod(this, 'html', [ html ]);
    },
    
    append: function Actor$append(el) {
        /// <param name="el" type="jQueryObject">
        /// </param>
        /// <returns type="Actor"></returns>
        return Actor.callBaseMethod(this, 'append', [ el ]);
    },
    
    prepend: function Actor$prepend(el) {
        /// <param name="el" type="jQueryObject">
        /// </param>
        /// <returns type="Actor"></returns>
        return Actor.callBaseMethod(this, 'prepend', [ el ]);
    },
    
    appendTo: function Actor$appendTo(el) {
        /// <param name="el" type="jQueryObject">
        /// </param>
        /// <returns type="Actor"></returns>
        return Actor.callBaseMethod(this, 'appendTo', [ el ]);
    },
    
    prependTo: function Actor$prependTo(el) {
        /// <param name="el" type="jQueryObject">
        /// </param>
        /// <returns type="Actor"></returns>
        return Actor.callBaseMethod(this, 'prependTo', [ el ]);
    },
    
    addClass: function Actor$addClass(classNames) {
        /// <param name="classNames" type="String">
        /// </param>
        /// <returns type="Actor"></returns>
        return Actor.callBaseMethod(this, 'addClass', [ classNames ]);
    }
}


////////////////////////////////////////////////////////////////////////////////
// Ask

Ask = function Ask() {
    /// <field name="FadeSpeed" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="CancelFace" type="String">
    /// </field>
    /// <field name="Message" type="String">
    /// </field>
    /// <field name="Msg" type="String">
    /// </field>
    /// <field name="OkFace" type="String">
    /// </field>
    /// <field name="SkipFace" type="String">
    /// </field>
    /// <field name="Title" type="String">
    /// </field>
    /// <field name="Value" type="String">
    /// </field>
    /// <field name="_awp$3" type="Await">
    /// </field>
    Ask.initializeBase(this);
    this.element = $("<div class='Ask AboveHider'/>").css({ position: 'absolute' });
}
Ask.prototype = {
    CancelFace: 'Cancel',
    Message: null,
    Msg: null,
    OkFace: 'OK',
    SkipFace: 'Skip',
    Title: '',
    Value: null,
    _awp$3: null,
    
    okAw: function Ask$okAw(awp, properties) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="properties" type="Object">
        /// </param>
        this._stdTitle$3(awp, properties);
        this._stdContent$3();
        this._stdBtns$3(ss.Delegate.create(this, this._okEv$3));
        DomElement.focusElementAw(Await.get_asyncAw(), $('.OkBtn', this.element));
    },
    
    okCancelAw: function Ask$okCancelAw(awp, properties) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="properties" type="Object">
        /// </param>
        this._stdTitle$3(awp, properties);
        this._stdContent$3();
        this._stdBtns$3(ss.Delegate.create(this, this._okEv$3), ss.Delegate.create(this, this._cancelEv$3));
        DomElement.focusElementAw(Await.get_asyncAw(), $('.OkBtn', this.element));
    },
    
    textAw: function Ask$textAw(awp, properties) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="properties" type="Object">
        /// </param>
        this._stdTitle$3(awp, properties);
        $("<input type='text' class='Content'/>").appendTo(this.element).val(this.Value || '');
        this._stdBtns$3(ss.Delegate.create(this, this._okEvText$3), ss.Delegate.create(this, this._cancelEv$3));
        DomElement.focusElementAw(Await.get_asyncAw(), $('input[type=text]', this.element));
    },
    
    _stdTitle$3: function Ask$_stdTitle$3(awp, properties) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="properties" type="Object">
        /// </param>
        this._awp$3 = awp;
        if (!this.tryLoadProperties(properties)) {
            this.Message = properties.toString();
        }
        $('<h1/>').appendTo(this.element).html(this.Msg || this.Message);
    },
    
    _stdContent$3: function Ask$_stdContent$3() {
        $("<div class='Content'/>").appendTo(this.element);
    },
    
    _stdBtns$3: function Ask$_stdBtns$3(okEv, cancelEv) {
        /// <param name="okEv" type="Function">
        /// </param>
        /// <param name="cancelEv" type="Function">
        /// </param>
        if (cancelEv != null) {
            $("<button class='CancelBtn'/>").appendTo(this.element).html(this.CancelFace).click(cancelEv);
        }
        $("<button class='OkBtn'/>").appendTo(this.element).html(this.OkFace).click(okEv);
        this.returnKeyAction(okEv);
        this.escapeKeyAction(cancelEv || ss.Delegate.create(this, this._cancelEv$3));
        Cluster.hider(true);
        this.element.hide().appendTo(document.body).fadeInW(250).position({ my: 'center top', at: 'center top', of: window.self, offset: '0 200', collision: 'fit fit' });
    },
    
    _okEvText$3: function Ask$_okEvText$3(e) {
        /// <param name="e" type="jQueryEvent">
        /// </param>
        this._awp$3.doneWith('result', $('input[type=text]', this.element).getFValue());
        this._destroyEv$3(e, $('input[type=text]', this.element).getFValue());
    },
    
    _okEv$3: function Ask$_okEv$3(e) {
        /// <param name="e" type="jQueryEvent">
        /// </param>
        this._destroyEv$3(e, true);
    },
    
    _cancelEv$3: function Ask$_cancelEv$3(e) {
        /// <param name="e" type="jQueryEvent">
        /// </param>
        this._destroyEv$3(e, false);
    },
    
    _destroyEv$3: function Ask$_destroyEv$3(e, value) {
        /// <param name="e" type="jQueryEvent">
        /// </param>
        /// <param name="value" type="Object">
        /// </param>
        DomElement.cancelEvent(e);
        this.returnKeyAction();
        this.escapeKeyAction();
        Cluster.hider(false);
        this.element.fadeOutW(250, ss.Delegate.create(this, function() {
            this.element.remove();
            this._awp$3.doneWith('result', value);
        }));
    }
}


////////////////////////////////////////////////////////////////////////////////
// DropTarget

DropTarget = function DropTarget() {
}
DropTarget.dragOverEv = function DropTarget$dragOverEv(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    DomElement.cancelEvent(e);
}
DropTarget.dropDumpEv = function DropTarget$dropDumpEv(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    var result = DropTarget.dropObject(e);
    Inform.debug('MouseX {0}, {1}', result['mouseX'], e.offsetX);
    Inform.dump(result);
}
DropTarget.dropObject = function DropTarget$dropObject(e) {
    /// <summary>
    /// Creates a dicitonary of the drop attributes.
    /// Most useful are "url" and "html".
    /// </summary>
    /// <param name="e" type="jQueryEvent">
    /// The event
    /// </param>
    /// <returns type="Object"></returns>
    DomElement.cancelEvent(e);
    var result = {};
    var target = $(e.target);
    result['mouseX'] = e.pageX || e.originalEvent.pageX;
    result['mouseY'] = e.pageY || e.originalEvent.pageY;
    result['target'] = target;
    result['selectTo'] = target.selecTo();
    try {
        var types = e.originalEvent.dataTransfer.types;
        result['types'] = types;
        if (types.contains('url')) {
            var data = e.originalEvent.dataTransfer.getData('url');
            if (data != null) {
                result['imgurl'] = DropTarget.getUrl(data);
            }
        }
        if (types.contains('text/html')) {
            var data = e.originalEvent.dataTransfer.getData('text/html').toLocaleString();
            result['html'] = data;
            var el = $(data);
            var src = el.find('img').attr('src');
            if (String.isNullOrEmpty(src)) {
                src = el.attr('src');
            }
            result['srcurl'] = src;
            var idx = data.indexOf('imgurl=');
            if (idx > 0) {
                var u = data.substr(idx + 7).split('&')[0];
                result['htmlurl'] = decodeURIComponent(u);
            }
        }
        if (types.contains('text/uri-list')) {
            var data = e.originalEvent.dataTransfer.getData('text/uri-list');
            result['uriurl'] = DropTarget.getUrl(data);
        }
        if (types.contains('text')) {
            var data = e.originalEvent.dataTransfer.getData('text');
            result['texturl'] = DropTarget.getUrl(data);
        }
        if (types.contains('text/plain')) {
            var data = e.originalEvent.dataTransfer.getData('text/plain');
            result['texturl2'] = DropTarget.getUrl(data);
        }
    }
    catch ($e1) {
    }
    result['url'] = result['imgurl'] || result['htmlurl'] || result['texturl'] || result['texturl2'] || result['uriurl'] || result['srcurl'];
    if (!ss.isValue(result['url'])) {
        result['url'] = null;
    }
    else if (!/^https?:/.test(result['url'])) {
        result['url'] = 'http://' + result['url'];
    }
    return result;
}
DropTarget.getUrl = function DropTarget$getUrl(txt) {
    /// <param name="txt" type="String">
    /// </param>
    /// <returns type="String"></returns>
    var q = txt.split('?')[1] || txt;
    var p = Request.loadNvp(q);
    return p['imgurl'];
}


////////////////////////////////////////////////////////////////////////////////
// Helpers

Helpers = function Helpers() {
}
Helpers.prp = function Helpers$prp(d, n, v) {
    /// <param name="d" type="Object">
    /// </param>
    /// <param name="n" type="String">
    /// </param>
    /// <param name="v" type="Object">
    /// </param>
    /// <returns type="Object"></returns>
    if (d[n]===false) {
        return null;
    }
    return d[n] || v;
}
Helpers.closeEv = function Helpers$closeEv(fn, arg1, arg2) {
    /// <param name="fn" type="System.Action`3">
    /// </param>
    /// <param name="arg1" type="Function">
    /// </param>
    /// <param name="arg2" type="Object">
    /// </param>
    /// <returns type="Function"></returns>
    return function(e) {
        fn(e, arg1, arg2);
    };
}


////////////////////////////////////////////////////////////////////////////////
// DDict

DDict = function DDict() {
    /// <field name="_dict" type="Object">
    /// </field>
    this._dict = {};
}
DDict.prototype = {
    
    add: function DDict$add(key, dj) {
        /// <param name="key" type="String">
        /// </param>
        /// <param name="dj" type="Object">
        /// </param>
        /// <returns type="DDict"></returns>
        this._dict[key] = dj;
        return this;
    },
    
    end: function DDict$end() {
        /// <returns type="Object"></returns>
        return this._dict;
    }
}


////////////////////////////////////////////////////////////////////////////////
// DList

DList = function DList() {
    /// <field name="_list" type="Array">
    /// </field>
    this._list = [];
}
DList.prototype = {
    
    add: function DList$add(dj) {
        /// <param name="dj" type="Object">
        /// </param>
        /// <returns type="DList"></returns>
        this._list.add(dj);
        return this;
    },
    
    end: function DList$end() {
        /// <returns type="Array"></returns>
        return this._list;
    }
}


////////////////////////////////////////////////////////////////////////////////
// Cluster

Cluster = function Cluster() {
    /// <field name="truples" type="Object" static="true">
    /// </field>
    /// <field name="elements" type="Object" static="true">
    /// </field>
    /// <field name="_hiderElement$1" type="jQueryObject" static="true">
    /// </field>
    /// <field name="_hiderCount$1" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="ClassName" type="String">
    /// </field>
    Cluster.initializeBase(this);
}
Cluster.hider = function Cluster$hider(hiderOn, opacity) {
    /// <param name="hiderOn" type="Boolean">
    /// </param>
    /// <param name="opacity" type="Number">
    /// </param>
    opacity = (opacity || 0.55);
    if (hiderOn) {
        if (Cluster._hiderCount$1++ > 0) {
            return;
        }
        Cluster._hiderElement$1 = $('<div/>').appendTo(document.body).css({ position: 'absolute', top: 0, left: 0, width: DomElement.documentWidth(), height: DomElement.documentHeight(), margin: 0, padding: 0, background: '#000', opacity: opacity }).addClass('HiderZee').show();
        Cluster._hiderElement$1.swallowAllMouseEvents();
    }
    else {
        if (--Cluster._hiderCount$1 > 0) {
            return;
        }
        var el = Cluster._hiderElement$1;
        Cluster._hiderElement$1 = null;
        FileBlobBase.svCnt++;
        el.fadeOut(200, function() {
            el.remove();
            FileBlobBase.svCnt--;
        });
    }
}
Cluster.glass = function Cluster$glass(clickFn) {
    /// <param name="clickFn" type="Function">
    /// </param>
    var glass = $("<div class='VirtualGlass'/>");
    glass.appendTo(document.body).css({ position: 'absolute', top: 0, left: 0, width: DomElement.documentWidth(), height: DomElement.documentHeight(), margin: 0, padding: 0, background: 'transparent' }).addClass('GlassZee').mousedown(function(e) {
        if (e.target === glass[0]) {
            Cluster.glassOff();
        }
        DomElement.cancelEvent(e);
    });
    glass.data('GlassOffFn', clickFn);
    $(window).unbind('resize.Glass').bind('resize.Glass', function() {
        var vg = $('.VirtualGlass');
        var fn = vg.data('GlassOffFn');
        vg.removeData('GlassOffFn');
        Cluster.glassOff();
        Cluster.glass(fn);
    });
}
Cluster.glassOff = function Cluster$glassOff() {
    $(window).unbind('resize.Glass');
    var glass = $('.VirtualGlass');
    if (glass.length > 0) {
        glass.each(function(i, domEl) {
            var ths = $(domEl);
            var clickFn = ths.data('GlassOffFn');
            ths.removeData('GlassOffFn');
            ths.remove();
            if (clickFn != null) {
                clickFn();
            }
        });
    }
}
Cluster.prototype = {
    ClassName: null,
    
    tryLoadProperties: function Cluster$tryLoadProperties(properties) {
        /// <param name="properties" type="Object">
        /// </param>
        /// <returns type="Boolean"></returns>
        if (typeof(properties) === 'object') {
            if (ss.isValue(properties)) {
                var $dict1 = properties;
                for (var $key2 in $dict1) {
                    var kv = { key: $key2, value: $dict1[$key2] };
                    try {
                        var d = this;
                        d[kv.key] = kv.value;
                    }
                    catch ($e3) {
                        throw new Error('Undefined property[' + kv.key + ']');
                    }
                }
            }
            return true;
        }
        return false;
    },
    
    hiderAw: function Cluster$hiderAw(awp, hiderOn, opacity) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="hiderOn" type="Boolean">
        /// </param>
        /// <param name="opacity" type="Number">
        /// </param>
        Cluster.hider(hiderOn, opacity);
        if (this.element != null) {
            if (hiderOn) {
                this.element.addClass('AboveHider');
            }
            else {
                this.element.removeClass('AboveHider');
            }
        }
        awp.done();
    }
}


////////////////////////////////////////////////////////////////////////////////
// EditHtml

EditHtml = function EditHtml(awp, edEl) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="edEl" type="jQueryObject">
    /// </param>
    /// <field name="eAwp" type="Await">
    /// </field>
    /// <field name="_eCss$3" type="Object">
    /// </field>
    /// <field name="edEl" type="jQueryObject">
    /// </field>
    /// <field name="textIn" type="String">
    /// </field>
    /// <field name="textarea" type="jQueryObject">
    /// </field>
    /// <field name="_autoErDiv$3" type="jQueryObject" static="true">
    /// </field>
    /// <field name="_autoEr$3" type="jQueryObject">
    /// </field>
    /// <field name="_regExLf$3" type="RegExp" static="true">
    /// </field>
    EditHtml.initializeBase(this);
    this.escapeKeyAction(ss.Delegate.create(this, this.cancel));
    this.eAwp = awp;
    this.edEl = edEl;
    this.element = $("<div class='EditContent'/>").appendTo(document.body);
    this.textIn = edEl.getFValueString();
    this.textarea = $('<textarea/>').appendTo(this.element).fValueString(this.textIn).blur(ss.Delegate.create(this, this.ok));
    this._eCss$3 = edEl.cloneEditCSS();
    this.textarea.css(this._eCss$3).bind('keyup', ss.Delegate.create(this, function(e) {
        if (Nsb.Classes.Truple.blackKey(e) || (e.which === 13 && e.shiftKey)) {
            this.textarea.css('height', this._autoHeight$3(this.textarea) + 'px');
        }
    })).bind('keydown', ss.Delegate.create(this, function(e) {
        if (e.which === 9) {
            this.next(e);
        }
        else if (e.which === 13) {
            if (e.shiftKey) {
                return;
            }
            DomElement.cancelEvent(e);
            this.textarea.blur();
            this.cont(e);
        }
        else if (e.which === 40) {
            window.setTimeout(ss.Delegate.create(this, function() {
                if (this.textarea.getSelection()['start'] === this.textarea.val().length) {
                    this.next(e);
                }
            }), 1);
        }
        else if (e.which === 38) {
            var sel = this.textarea.getSelection()['start'];
            window.setTimeout(ss.Delegate.create(this, function() {
                if (this.textarea.getSelection()['start'] === sel) {
                    this.prior(e);
                }
            }), 1);
        }
    }));
    new Await().addDx(ss.Delegate.create(this, function() {
        this.textarea.focus();
    })).commit();
}
EditHtml.prototype = {
    eAwp: null,
    _eCss$3: null,
    edEl: null,
    textIn: null,
    textarea: null,
    _autoEr$3: null,
    
    destroy: function EditHtml$destroy() {
        this.escapeKeyAction();
        this.element.remove();
    },
    
    ok: function EditHtml$ok(e) {
        /// <param name="e" type="jQueryEvent">
        /// </param>
        var txtOut = this.textarea.getFValueString();
        this.eAwp.set_item('changed', this.textIn !== txtOut);
        this.edEl.fValueString(txtOut);
        this.destroy();
        this.eAwp.done();
    },
    
    cancel: function EditHtml$cancel(e) {
        /// <param name="e" type="jQueryEvent">
        /// </param>
        this.destroy();
        throw new Error('User Cancelled');
    },
    
    cont: function EditHtml$cont(e) {
        /// <summary>
        /// What to do when shift-enter is pressed to signify edit is done
        /// and move on to possibly create a new list item.
        /// </summary>
        /// <param name="e" type="jQueryEvent">
        /// jQueryEvent
        /// </param>
    },
    
    next: function EditHtml$next(e) {
        /// <param name="e" type="jQueryEvent">
        /// </param>
    },
    
    prior: function EditHtml$prior(e) {
        /// <param name="e" type="jQueryEvent">
        /// </param>
    },
    
    _autoHeight$3: function EditHtml$_autoHeight$3(el) {
        /// <param name="el" type="jQueryObject">
        /// </param>
        /// <returns type="Number" integer="true"></returns>
        if (this._autoEr$3 == null) {
            if (EditHtml._autoErDiv$3 == null) {
                EditHtml._autoErDiv$3 = $("<div style='position:absolute;visibility:hidden'/>").appendTo(document.body);
            }
            this._autoEr$3 = $('<div/>').css(this._eCss$3).prependTo(EditHtml._autoErDiv$3);
            this._autoEr$3.css({ top: 0, height: 'auto', position: 'relative', overflow: 'visible' });
        }
        this._autoEr$3.html(el.val().replace(EditHtml._regExLf$3, '<br>'));
        return this._autoEr$3.height();
    }
}


////////////////////////////////////////////////////////////////////////////////
// Exceptions

Exceptions = function Exceptions() {
    /// <field name="missingAwaitDoneEr" type="String" static="true">
    /// </field>
    /// <field name="missingDomElement" type="String" static="true">
    /// </field>
    /// <field name="argumentNull" type="String" static="true">
    /// </field>
    /// <field name="recordNotExists" type="String" static="true">
    /// </field>
    /// <field name="newRecordExists" type="String" static="true">
    /// </field>
    /// <field name="invalidName" type="String" static="true">
    /// </field>
    /// <field name="userCancelled" type="String" static="true">
    /// </field>
    /// <field name="blobLoadError" type="String" static="true">
    /// </field>
    /// <field name="blobSaveError" type="String" static="true">
    /// </field>
    /// <field name="serviceLoginFailure" type="String" static="true">
    /// </field>
    /// <field name="fileIsNewer" type="String" static="true">
    /// </field>
    /// <field name="newUser" type="String" static="true">
    /// </field>
    /// <field name="invalidPageException" type="String" static="true">
    /// </field>
    /// <field name="sendMailError" type="String" static="true">
    /// </field>
    /// <field name="invalidTestCaseName" type="String" static="true">
    /// </field>
    /// <field name="invalidTestSuiteName" type="String" static="true">
    /// </field>
    /// <field name="invalidDataOperation" type="String" static="true">
    /// </field>
    /// <field name="notImplementedExceptionString" type="String" static="true">
    /// </field>
}
Exceptions.notImplementedException = function Exceptions$notImplementedException() {
    /// <returns type="Error"></returns>
    return new Error('Not Implimented');
}
Exceptions.format = function Exceptions$format(ex, msg) {
    /// <param name="ex" type="String">
    /// </param>
    /// <param name="msg" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return ex + ' : ' + msg;
}
Exceptions.fn = function Exceptions$fn(args) {
    /// <param name="args" type="Object">
    /// </param>
    /// <returns type="String"></returns>
    return args.callee.name || 'unknown';
}


////////////////////////////////////////////////////////////////////////////////
// FileBlobBase

FileBlobBase = function FileBlobBase() {
    /// <field name="_password" type="String" static="true">
    /// </field>
    /// <field name="_getUrl" type="String" static="true">
    /// </field>
    /// <field name="_putUrl" type="String" static="true">
    /// </field>
    /// <field name="_delUrl" type="String" static="true">
    /// </field>
    /// <field name="_apnUrl" type="String" static="true">
    /// </field>
    /// <field name="_dirUrl" type="String" static="true">
    /// </field>
    /// <field name="_encodeLzw64" type="String" static="true">
    /// </field>
    /// <field name="_fileExt" type="String" static="true">
    /// </field>
    /// <field name="svCnt" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="_modTime" type="Object" static="true">
    /// </field>
    /// <field name="_xfr" type="Object" static="true">
    /// </field>
}
FileBlobBase.retrieveBlobAw = function FileBlobBase$retrieveBlobAw(awp, partitionKey, rowKey, rxKey) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="partitionKey" type="String">
    /// </param>
    /// <param name="rowKey" type="String">
    /// </param>
    /// <param name="rxKey" type="String">
    /// </param>
    new Await().addDl(function(aw) {
        FileBlobBase.retrieveBlobStringAw(aw, partitionKey, rowKey, rxKey);
    }).handleDl('Blob Load Error', Await.rethrowAw).addDx(function(aw) {
        awp.set_item(rxKey, FileBlobBase._unpackage(aw.get_item(rxKey)));
    }).commit(awp);
}
FileBlobBase.storeBlobAw = function FileBlobBase$storeBlobAw(awp, partitionKey, rowKey, rxKey, blob) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="partitionKey" type="String">
    /// </param>
    /// <param name="rowKey" type="String">
    /// </param>
    /// <param name="rxKey" type="String">
    /// </param>
    /// <param name="blob" type="Object">
    /// </param>
    new Await().addDl(function(aw) {
        FileBlobBase.storeBlobStringAw(aw, partitionKey, rowKey, FileBlobBase._repackage(blob), rxKey);
    }).handleDl('Blob Save Error', Await.rethrowAw).addDx(function(aw) {
        awp.set_item(rxKey, aw.get_item(rxKey));
    }).commit(awp);
}
FileBlobBase.getBlobAw = function FileBlobBase$getBlobAw(awp, data) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="data" type="Object">
    /// </param>
    FileBlobBase.retrieveBlobAw(awp, data['PartitionKey'], data['RowKey'], 'result');
}
FileBlobBase.putBlobAw = function FileBlobBase$putBlobAw(awp, blob, data) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="blob" type="Object">
    /// </param>
    /// <param name="data" type="Object">
    /// </param>
    FileBlobBase.storeBlobAw(awp, data['PartitionKey'], data['RowKey'], 'result', blob);
}
FileBlobBase.retrieveBlobStringAw = function FileBlobBase$retrieveBlobStringAw(awp, partitionKey, rowKey, rxKey) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="partitionKey" type="String">
    /// </param>
    /// <param name="rowKey" type="String">
    /// </param>
    /// <param name="rxKey" type="String">
    /// </param>
    ss.Debug.assert(rowKey != null, 'rowKey != null');
    var fullKey = FileBlobBase._fullKey(partitionKey, rowKey);
    if (FileBlobBase._xfr[fullKey]) {
        window.setTimeout(function() {
            FileBlobBase.retrieveBlobStringAw(awp, partitionKey, rowKey, rxKey);
        }, 13);
        return;
    }
    rxKey = rxKey || 'result';
    var payload = {};
    payload['password'] = 'SuperBaby';
    payload['path'] = partitionKey;
    payload['file'] = rowKey + '.txt';
    var options = {};
    options.url = 'data/file.get.php';
    options.data = payload;
    options.dataType = 'jsonp';
    options.type = 'GET';
    options.success = function(fbo, textStatus, request1) {
        FileBlobBase.svCnt--;
        FileBlobBase._xfr[fullKey] = false;
        try {
            if (!fbo.result) {
                throw new Error('Blob Load Error');
            }
            awp.set_item(rxKey, FileBlobBase._decode(fbo.content));
            if (fbo.exists) {
                FileBlobBase._modTime[fullKey] = fbo.lastChanged;
            }
        }
        catch (ex) {
            Inform.trace('Unable to retrieve pkg {0}, exception={1}', FileBlobBase._fullKey(partitionKey, rowKey), ex);
            awp.handle(new Error('Blob Load Error'));
            return;
        }
        awp.done();
    };
    options.error = function(request, textStatus, error) {
        FileBlobBase.svCnt--;
        FileBlobBase._xfr[fullKey] = false;
        Inform.error('Error retrieving pkg {0}/{1}, {2} {3}', partitionKey, rowKey, textStatus, error);
        awp.handle(new Error('Blob Load Error'));
    };
    FileBlobBase._xfr[fullKey] = true;
    FileBlobBase.svCnt++;
    $.ajax(options);
}
FileBlobBase.storeBlobStringAw = function FileBlobBase$storeBlobStringAw(awp, partitionKey, rowKey, content, rxKey) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="partitionKey" type="String">
    /// </param>
    /// <param name="rowKey" type="String">
    /// </param>
    /// <param name="content" type="String">
    /// </param>
    /// <param name="rxKey" type="String">
    /// </param>
    rxKey = rxKey || 'result';
    FileBlobBase._outPkgStringAw(awp, partitionKey, rowKey, rxKey, content, 'data/file.put.php', false);
}
FileBlobBase.appendBlobStringAw = function FileBlobBase$appendBlobStringAw(awp, partitionKey, rowKey, rxKey, content) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="partitionKey" type="String">
    /// </param>
    /// <param name="rowKey" type="String">
    /// </param>
    /// <param name="rxKey" type="String">
    /// </param>
    /// <param name="content" type="String">
    /// </param>
    FileBlobBase._outPkgStringAw(awp, partitionKey, rowKey, rxKey, content, 'data/file.app.php', true);
}
FileBlobBase._outPkgStringAw = function FileBlobBase$_outPkgStringAw(awp, partitionKey, rowKey, rxKey, content, url, append) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="partitionKey" type="String">
    /// </param>
    /// <param name="rowKey" type="String">
    /// </param>
    /// <param name="rxKey" type="String">
    /// </param>
    /// <param name="content" type="String">
    /// </param>
    /// <param name="url" type="String">
    /// </param>
    /// <param name="append" type="Boolean">
    /// </param>
    ss.Debug.assert(rowKey != null, 'rowKey != null');
    var fullKey = FileBlobBase._fullKey(partitionKey, rowKey);
    if (FileBlobBase._xfr[fullKey]) {
        Inform.debug('Waiting on {0}', fullKey);
        window.setTimeout(function() {
            FileBlobBase._outPkgStringAw(awp, partitionKey, rowKey, rxKey, content, url, append);
        }, 13);
        return;
    }
    var payload = {};
    payload['password'] = 'SuperBaby';
    payload['createFile'] = 'true';
    payload['createPath'] = 'true';
    payload['path'] = partitionKey;
    payload['file'] = rowKey + '.txt';
    payload['priorTime'] = (FileBlobBase._modTime[FileBlobBase._fullKey(partitionKey, rowKey)] || 0);
    payload['forceSave'] = append;
    payload['content64'] = Nsb.Encoder.encode64(FileBlobBase._encode(content));
    var options = {};
    options.url = url;
    options.data = payload;
    options.type = 'POST';
    options.success = function(fbo, textStatus, request1) {
        FileBlobBase.svCnt--;
        var msg = null;
        try {
            if (!fbo.result) {
                if (fbo.fileNewer) {
                    Inform.warn('Trying to write to a newer file {0}', FileBlobBase._fullKey(partitionKey, rowKey));
                    throw new Error('File is newer');
                }
                msg = (ss.isNullOrUndefined(fbo)) ? '' : fbo.msg;
                throw new Error('Blob Save Error');
            }
            FileBlobBase._modTime[FileBlobBase._fullKey(partitionKey, rowKey)] = fbo.lastChanged;
        }
        catch (ex) {
            switch (ex.message) {
                case 'File is newer':
                    FileBlobBase._xfr[fullKey] = false;
                    awp.handle(ex);
                    return;
            }
            Inform.warn('Not able to send pkg {0}, error={1}', FileBlobBase._fullKey(partitionKey, rowKey), (msg || ex.toString()));
            FileBlobBase._xfr[fullKey] = false;
            awp.handle(new Error('Blob Save Error'));
            return;
        }
        FileBlobBase._xfr[fullKey] = false;
        awp.set_item(rxKey, true);
        awp.done();
    };
    options.error = function(request, textStatus, error) {
        FileBlobBase.svCnt--;
        FileBlobBase._xfr[fullKey] = false;
        Inform.error('Error sending pkg {0}, {1} : {2}', FileBlobBase._fullKey(partitionKey, rowKey), textStatus, error);
        awp.handle(new Error('Blob Load Error'));
    };
    FileBlobBase.svCnt++;
    FileBlobBase._xfr[fullKey] = true;
    $.ajax(options);
}
FileBlobBase.deleteItemAw = function FileBlobBase$deleteItemAw(awp, partitionKey, rowKey) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="partitionKey" type="String">
    /// </param>
    /// <param name="rowKey" type="String">
    /// </param>
    var payload = {};
    payload['password'] = 'SuperBaby';
    payload['path'] = partitionKey;
    payload['file'] = rowKey + '.txt';
    var options = {};
    options.url = 'data/file.del.php';
    options.data = payload;
    options.dataType = 'jsonp';
    options.type = 'GET';
    options.success = function(fbo, textStatus, request1) {
        FileBlobBase.svCnt--;
        try {
            if (ss.isNullOrUndefined(fbo) || !fbo.result) {
                throw new Error('Blob Load Error');
            }
        }
        catch (ex) {
            Inform.trace('Unable to delete pkg {0}/{1}, exception={3}', partitionKey, rowKey, ex);
            awp.handle(new Error('Blob Load Error'));
            return;
        }
        awp.done();
    };
    options.error = function(request, textStatus, error) {
        FileBlobBase.svCnt--;
        Inform.error('Error deleting pkg {0}/{1}, {2} {3}', partitionKey, rowKey, textStatus, error);
        awp.handle(new Error('Blob Load Error'));
    };
    FileBlobBase.svCnt++;
    $.ajax(options);
}
FileBlobBase.getDirAw = function FileBlobBase$getDirAw(awp, partitionKey) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="partitionKey" type="String">
    /// </param>
    var payload = {};
    payload['password'] = 'SuperBaby';
    payload['path'] = partitionKey;
    var options = {};
    options.url = 'data/file.dir.php';
    options.data = payload;
    options.dataType = 'jsonp';
    options.type = 'GET';
    options.success = function(data, textStatus, request1) {
        FileBlobBase.svCnt--;
        try {
            data = JSON.parse(data);
            if (ss.isNullOrUndefined(data) || !data.result) {
                throw new Error('Blob Load Error');
            }
        }
        catch (ex) {
            Inform.trace('Unable to get file list {0}, exception={1}', partitionKey, ex);
            awp.handle(new Error('Blob Load Error'));
            return;
        }
        awp.set_item('result', data);
        awp.done();
    };
    options.error = function(request, textStatus, error) {
        FileBlobBase.svCnt--;
        Inform.error('Error getting file list {0}, {1} {2}', partitionKey, textStatus, error);
        awp.handle(new Error('Blob Load Error'));
    };
    FileBlobBase.svCnt++;
    $.ajax(options);
}
FileBlobBase.forceStoreBlob = function FileBlobBase$forceStoreBlob(partitionKey, rowKey) {
    /// <param name="partitionKey" type="String">
    /// </param>
    /// <param name="rowKey" type="String">
    /// </param>
    FileBlobBase._modTime[FileBlobBase._fullKey(partitionKey, rowKey)] = 0;
}
FileBlobBase._fullKey = function FileBlobBase$_fullKey(partitionKey, rowKey) {
    /// <param name="partitionKey" type="String">
    /// </param>
    /// <param name="rowKey" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return partitionKey + '/' + rowKey;
}
FileBlobBase._repackage = function FileBlobBase$_repackage(blob) {
    /// <param name="blob" type="Object">
    /// </param>
    /// <returns type="String"></returns>
    try {
        return JSON.stringify(blob);
    }
    catch (ex) {
        Inform.error('Error stringifying blob: {0}', ex);
    }
    return '';
}
FileBlobBase._unpackage = function FileBlobBase$_unpackage(s) {
    /// <param name="s" type="String">
    /// </param>
    /// <returns type="Object"></returns>
    try {
        if (!String.isNullOrEmpty(s)) {
            return JSON.parse(s);
        }
    }
    catch (ex) {
        Inform.error('Error parsing blob: {0}', ex);
    }
    return '';
}
FileBlobBase._encode = function FileBlobBase$_encode(s) {
    /// <param name="s" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return s;
}
FileBlobBase._decode = function FileBlobBase$_decode(s) {
    /// <param name="s" type="String">
    /// </param>
    /// <returns type="String"></returns>
    var pfx = (ss.isNullOrUndefined(s)) ? '' : s.substr(0, 6);
    switch (pfx) {
        case 'VXLZ64':
            return Nsb.Encoder.lzwDecode(Nsb.Encoder.decode64(s.substr(6)));
        default:
            return (String.isNullOrEmpty(s)) ? '' : s;
    }
}
FileBlobBase.cleanListData = function FileBlobBase$cleanListData(txt) {
    /// <param name="txt" type="String">
    /// </param>
    /// <returns type="String"></returns>
    var s = 0;
    var e = txt.length;
    if (txt.charCodeAt(0) === 65279) {
        s++;
    }
    while (e > 0 && '\r\n\t,; '.indexOf(txt.charAt(e - 1)) !== -1) {
        e--;
    }
    return txt.substring(s, e);
}
FileBlobBase.simpleList = function FileBlobBase$simpleList(list) {
    /// <param name="list" type="Object">
    /// </param>
    /// <returns type="String"></returns>
    var nl = JSON.stringify(list);
    nl = nl.replace(DomElement.regMe('/^\\[(.*)\\]$/'), '$1');
    return nl.replaceAll('},{', '},\r\n{');
}


////////////////////////////////////////////////////////////////////////////////
// Formulas

Formulas = function Formulas() {
    /// <field name="_idCnt" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="newIdPrefix" type="String" static="true">
    /// </field>
}
Formulas.randomOf = function Formulas$randomOf(range) {
    /// <param name="range" type="Number" integer="true">
    /// </param>
    /// <returns type="Number" integer="true"></returns>
    return Math.floor(Math.random() * range);
}
Formulas.get_newId = function Formulas$get_newId() {
    /// <summary>
    /// Generate a new unique id composed of [user]q[time]n[count]
    /// </summary>
    /// <value type="String"></value>
    return (Formulas.newIdPrefix || Formulas.randomOf(10000000).toString()) + 'q' + new Date().getTime() + 'n' + (Formulas._idCnt = (Formulas._idCnt > 99999) ? 1 : Formulas._idCnt + 1);
}
Formulas.hash = function Formulas$hash(s) {
    /// <param name="s" type="String">
    /// </param>
    /// <returns type="Number" integer="true"></returns>
    var hash = 0;
    for (var i = 0; i < s.length; i++) {
        hash += (s.charCodeAt(i) * (i + 1));
    }
    return Math.abs(hash);
}
Formulas.distance = function Formulas$distance(lat1, lon1, lat2, lon2, unit) {
    /// <param name="lat1" type="Number">
    /// </param>
    /// <param name="lon1" type="Number">
    /// </param>
    /// <param name="lat2" type="Number">
    /// </param>
    /// <param name="lon2" type="Number">
    /// </param>
    /// <param name="unit" type="String">
    /// </param>
    /// <returns type="Number"></returns>
    var radlat1 = Math.PI * lat1 / 180;
    var radlat2 = Math.PI * lat2 / 180;
    var theta = lon1 - lon2;
    var radtheta = Math.PI * theta / 180;
    var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
    dist = Math.acos(dist);
    dist = dist * 180 / Math.PI;
    dist = dist * 60 * 1.1515;
    if (unit === 'K') {
        dist = dist * 1.609344;
    }
    if (unit === 'N') {
        dist = dist * 0.8684;
    }
    return dist;
}


////////////////////////////////////////////////////////////////////////////////
// PkgBase

PkgBase = function PkgBase() {
    /// <field name="_storeLcl$1" type="Boolean">
    /// </field>
    /// <field name="resultRx" type="String" static="true">
    /// </field>
    PkgBase.initializeBase(this);
    this._storeLcl$1 = false;
}
PkgBase.prototype = {
    _storeLcl$1: false,
    
    appendLcl: function PkgBase$appendLcl(partitionKey, rowKey, content) {
        /// <param name="partitionKey" type="String">
        /// </param>
        /// <param name="rowKey" type="String">
        /// </param>
        /// <param name="content" type="String">
        /// </param>
        if (!this._storeLcl$1) {
            return;
        }
        var pkg = window.localStorage.getItem(rowKey) || '';
        var jsonPkg = pkg + ((String.isNullOrEmpty(pkg)) ? '' : ',') + content;
        window.localStorage.setItem(partitionKey + rowKey, jsonPkg);
    },
    
    getLcl: function PkgBase$getLcl(partitionKey, rowKey) {
        /// <param name="partitionKey" type="String">
        /// </param>
        /// <param name="rowKey" type="String">
        /// </param>
        /// <returns type="String"></returns>
        if (!this._storeLcl$1) {
            return null;
        }
        return window.localStorage.getItem(partitionKey + rowKey);
    }
}


////////////////////////////////////////////////////////////////////////////////
// CloudMail

CloudMail = function CloudMail() {
    /// <field name="_sendUrl" type="String" static="true">
    /// </field>
}
CloudMail.sendMailAw = function CloudMail$sendMailAw(awp, mail) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="mail" type="Object">
    /// </param>
    var options = {};
    options.url = 'http://snalp.org/yoshi/data/sendmail.php';
    options.data = mail;
    options.dataType = 'json';
    options.type = 'POST';
    options.success = function(data, textStatus, request1) {
        awp.done();
    };
    options.error = function(request, textStatus, error) {
        Inform.error('Error sending mail {0} {1}', textStatus, error);
        awp.handle(new Error('Send Mail Error'));
    };
    $.ajax(options);
}


////////////////////////////////////////////////////////////////////////////////
// Rx

Rx = function Rx() {
    /// <field name="hasEndSpace" type="RegExp" static="true">
    /// </field>
    /// <field name="whiteSpace" type="RegExp" static="true">
    /// </field>
    /// <field name="cssFilter" type="RegExp" static="true">
    /// </field>
}


////////////////////////////////////////////////////////////////////////////////
// Strings

Strings = function Strings() {
    /// <field name="_rxSquish" type="RegExp" static="true">
    /// </field>
}
Strings.paraCase = function Strings$paraCase(s) {
    /// <param name="s" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return s.substr(0, 1).toUpperCase() + s.substr(1);
}
Strings.paraSquishCase = function Strings$paraSquishCase(s) {
    /// <param name="s" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return Strings.paraCase(s.replace(Strings._rxSquish, ''));
}


////////////////////////////////////////////////////////////////////////////////
// TestInstance

TestInstance = function TestInstance() {
    /// <field name="theTest" type="Object" static="true">
    /// </field>
}
TestInstance.addInstance = function TestInstance$addInstance(cls) {
    /// <param name="cls" type="Object">
    /// </param>
    if (TestInstance.theTest != null) {
        var fn = Test.addInstance;
        ss.Debug.assert(fn != null, 'Test.addInstance != null');
        if (fn != null) {
            fn(cls);
        }
    }
}


////////////////////////////////////////////////////////////////////////////////
// TrueForm

TrueForm = function TrueForm() {
}
TrueForm.prototype = {
    
    fillFormByName: function TrueForm$fillFormByName() {
        var $dict1 = this;
        for (var $key2 in $dict1) {
            var p = { key: $key2, value: $dict1[$key2] };
            if (typeof(p.value) !== 'function') {
                $('input[name=' + p.key + ']').val(p.value.toString());
            }
        }
    },
    
    scoopFormByName: function TrueForm$scoopFormByName() {
        var data = this;
        var $dict1 = data;
        for (var $key2 in $dict1) {
            var p = { key: $key2, value: $dict1[$key2] };
            if (typeof(p.value) !== 'function') {
                switch (typeof(data[p.key])) {
                    case 'boolean':
                        data[p.key] = Boolean.parse($('input[name=' + p.key + ']').val());
                        break;
                    case 'number':
                        data[p.key] = parseInt($('input[name=' + p.key + ']').val());
                        break;
                    default:
                        data[p.key] = $('input[name=' + p.key + ']').val();
                        break;
                }
            }
        }
    },
    
    fillFormByClass: function TrueForm$fillFormByClass() {
        var $dict1 = this;
        for (var $key2 in $dict1) {
            var p = { key: $key2, value: $dict1[$key2] };
            var classKey = p.key.substr(0, 1).toUpperCase() + p.key.substr(1);
            if (typeof(p.value) !== 'function') {
                $('.' + classKey).fValueString(p.value.toString());
            }
        }
    },
    
    scoopFormByClass: function TrueForm$scoopFormByClass() {
        var data = this;
        var $dict1 = data;
        for (var $key2 in $dict1) {
            var p = { key: $key2, value: $dict1[$key2] };
            var classKey = p.key.substr(0, 1).toUpperCase() + p.key.substr(1);
            if (typeof(p.value) !== 'function') {
                switch (typeof(data[p.key])) {
                    case 'boolean':
                        data[p.key] = Boolean.parse($('.' + classKey).getFValueString());
                        break;
                    case 'number':
                        data[p.key] = parseInt($('.' + classKey).getFValueString());
                        break;
                    default:
                        data[p.key] = $('.' + classKey).getFValueString();
                        break;
                }
            }
        }
    }
}


////////////////////////////////////////////////////////////////////////////////
// Nsb.Classes.Truple

Nsb.Classes.Truple = function Nsb_Classes_Truple() {
    /// <field name="_tabIndex$3" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="_arrowCodes$3" type="Array" elementType="Number" elementInteger="true" static="true">
    /// </field>
    /// <field name="_blackCodes$3" type="Array" elementType="Number" elementInteger="true" static="true">
    /// </field>
    Nsb.Classes.Truple.initializeBase(this);
}
Nsb.Classes.Truple.scoopDataTo = function Nsb_Classes_Truple$scoopDataTo(data) {
    /// <param name="data" type="Object">
    /// </param>
    var input = $('body .Truple .Input');
    input.each(function() {
        var key = $(this).data('fieldName');
        var value = $(this).getFValue();
        data[key] = value;
        return true;
    });
}
Nsb.Classes.Truple.fillDataFromAw = function Nsb_Classes_Truple$fillDataFromAw(awp, data) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="data" type="Object">
    /// </param>
    new Await().waitDx(function() {
        return $('body .Truple .Input').length > 0;
    }, 500).addDx(function() {
        Nsb.Classes.Truple.fillDataFrom(data);
    }).commit(awp);
}
Nsb.Classes.Truple.fillDataFrom = function Nsb_Classes_Truple$fillDataFrom(data) {
    /// <param name="data" type="Object">
    /// </param>
    var input = $('body .Truple .Input');
    input.each(function() {
        var key = $(this).data('fieldName');
        if (Object.keyExists(data, key)) {
            var value = data[key];
            $(this).fValue(value);
        }
        return true;
    });
}
Nsb.Classes.Truple.eachTruple = function Nsb_Classes_Truple$eachTruple(fn) {
    /// <param name="fn" type="Function">
    /// </param>
    var input = $('body .Truple');
    input.each(fn);
}
Nsb.Classes.Truple.eachInput = function Nsb_Classes_Truple$eachInput(fn) {
    /// <param name="fn" type="Function">
    /// </param>
    var input = $('body .Truple .Input');
    input.each(fn);
}
Nsb.Classes.Truple._isKey$3 = function Nsb_Classes_Truple$_isKey$3(k, codes) {
    /// <param name="k" type="Number" integer="true">
    /// </param>
    /// <param name="codes" type="Array" elementType="Number" elementInteger="true">
    /// </param>
    /// <returns type="Boolean"></returns>
    for (var i = 0; i < Nsb.Classes.Truple._blackCodes$3.length; i += 2) {
        if (k >= codes[i] && k <= codes[i + 1]) {
            return true;
        }
    }
    return false;
}
Nsb.Classes.Truple.arrowKey = function Nsb_Classes_Truple$arrowKey(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    /// <returns type="Boolean"></returns>
    return Nsb.Classes.Truple._isKey$3(e.which, Nsb.Classes.Truple._arrowCodes$3);
}
Nsb.Classes.Truple.blackKey = function Nsb_Classes_Truple$blackKey(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    /// <returns type="Boolean"></returns>
    return Nsb.Classes.Truple._isKey$3(e.which, Nsb.Classes.Truple._blackCodes$3);
}
Nsb.Classes.Truple.changeKey = function Nsb_Classes_Truple$changeKey(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    /// <returns type="Boolean"></returns>
    switch (e.target.tagName.toLowerCase()) {
        case 'select':
            return Nsb.Classes.Truple.arrowKey(e);
    }
    return Nsb.Classes.Truple.blackKey(e);
}
Nsb.Classes.Truple.prototype = {
    
    _buildTruple$3: function Nsb_Classes_Truple$_buildTruple$3(type, fieldName, appendTo) {
        /// <param name="type" type="String">
        /// </param>
        /// <param name="fieldName" type="String">
        /// </param>
        /// <param name="appendTo" type="Nsb.Classes.Truple">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        var key = Strings.paraSquishCase(fieldName);
        appendTo = (appendTo || this.element);
        var ie = $(type);
        if (ie.is('input,textarea,select,button')) {
            ie.addClass('Input').data('fieldName', fieldName).attr('tabindex', (++Nsb.Classes.Truple._tabIndex$3).toString());
        }
        var tu = new Nsb.Classes.Truple().fromHtml("<div class='Truple'/>").addClass(key).appendTo(appendTo).append($("<span class='Label'/>")).append(ie);
        Cluster.truples[fieldName] = tu;
        Cluster.elements[fieldName] = tu.element;
        return tu;
    },
    
    _buildTrupleBtn$3: function Nsb_Classes_Truple$_buildTrupleBtn$3(type, fieldName, appendTo) {
        /// <param name="type" type="String">
        /// </param>
        /// <param name="fieldName" type="String">
        /// </param>
        /// <param name="appendTo" type="Nsb.Classes.Truple">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        appendTo = (appendTo || this.element);
        return new Nsb.Classes.Truple().fromHtml("<div class='Truple'/>").addClass(fieldName.substr(0, 1).toUpperCase() + fieldName.substr(1)).appendTo(appendTo).append($(type).addClass('Control').data('fieldName', fieldName));
    },
    
    fromHtml: function Nsb_Classes_Truple$fromHtml(html) {
        /// <param name="html" type="String">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        Nsb.Classes.Truple.callBaseMethod(this, 'fromHtml', [ html ]);
        this.element.data('truple', this);
        return this;
    },
    
    input: function Nsb_Classes_Truple$input(fieldName, tu) {
        /// <param name="fieldName" type="String">
        /// </param>
        /// <param name="tu" type="Nsb.Classes.Truple">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        return this._buildTruple$3("<input type='text'/>", fieldName, tu).addClass('Text');
    },
    
    checkbox: function Nsb_Classes_Truple$checkbox(fieldName, tu) {
        /// <param name="fieldName" type="String">
        /// </param>
        /// <param name="tu" type="Nsb.Classes.Truple">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        return this._buildTruple$3("<input type='checkbox'/>", fieldName, tu).addClass('Checkbox');
    },
    
    selectBox: function Nsb_Classes_Truple$selectBox(fieldName, tu) {
        /// <param name="fieldName" type="String">
        /// </param>
        /// <param name="tu" type="Nsb.Classes.Truple">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        return this._buildTruple$3('<select/>', fieldName, tu).addClass('Select');
    },
    
    textarea: function Nsb_Classes_Truple$textarea(fieldName, tu) {
        /// <param name="fieldName" type="String">
        /// </param>
        /// <param name="tu" type="Nsb.Classes.Truple">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        return this._buildTruple$3('<textarea/>', fieldName, tu).addClass('Textarea');
    },
    
    button: function Nsb_Classes_Truple$button(fieldName, tu) {
        /// <param name="fieldName" type="String">
        /// </param>
        /// <param name="tu" type="Nsb.Classes.Truple">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        return this._buildTrupleBtn$3('<button/>', fieldName, tu).addClass('Button');
    },
    
    multipleChoice: function Nsb_Classes_Truple$multipleChoice(fieldName, question) {
        /// <param name="fieldName" type="String">
        /// </param>
        /// <param name="question" type="Object">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        var mc = this._buildTruple$3('<dl/>', fieldName).addClass('MultipleChoice');
        var dl = $('dl', mc.element);
        var qq = question['question'].toString();
        if (Object.keyExists(question, 'alias')) {
            qq = String.format('Hi {0},<br>{1}', question['alias'], qq);
        }
        $('<dt/>').appendTo(dl).html(qq);
        var $dict1 = question['answers'];
        for (var $key2 in $dict1) {
            var p = { key: $key2, value: $dict1[$key2] };
            var answer = $('<dd/>').appendTo(dl).html(p.value);
            $("<input type='radio' class='Radio'/>").prependTo(answer).attr('name', fieldName).attr('value', p.key);
        }
        if (question['hide']) {
            mc.element.hide();
        }
        return mc;
    },
    
    subHtml: function Nsb_Classes_Truple$subHtml(s, html) {
        /// <param name="s" type="String">
        /// </param>
        /// <param name="html" type="String">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        this.select(s).html(html);
        return this;
    },
    
    subValue: function Nsb_Classes_Truple$subValue(s, value) {
        /// <param name="s" type="String">
        /// </param>
        /// <param name="value" type="String">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        var el = this.select(s);
        if (el.is('input, textarea, select')) {
            el.val(value);
        }
        else {
            el.html(value);
        }
        return this;
    },
    
    inputElement: function Nsb_Classes_Truple$inputElement() {
        /// <returns type="jQueryObject"></returns>
        return this.select('.Input');
    },
    
    value: function Nsb_Classes_Truple$value(value) {
        /// <param name="value" type="String">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        return this.subValue('.Input', value);
    },
    
    subAttr: function Nsb_Classes_Truple$subAttr(s, attr, value) {
        /// <param name="s" type="String">
        /// </param>
        /// <param name="attr" type="String">
        /// </param>
        /// <param name="value" type="String">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        this.select(s).attr(attr, value);
        return this;
    },
    
    subOptions: function Nsb_Classes_Truple$subOptions(s, items) {
        /// <param name="s" type="String">
        /// </param>
        /// <param name="items" type="Object">
        /// </param>
        /// <returns type="Nsb.Classes.Truple"></returns>
        var el = this.select(s);
        var $dict1 = items;
        for (var $key2 in $dict1) {
            var p = { key: $key2, value: $dict1[$key2] };
            el.append($('<option/>').attr('value', p.key).html(p.value));
        }
        return this;
    },
    
    setOptions: function Nsb_Classes_Truple$setOptions(options) {
        /// <param name="options" type="Object">
        /// </param>
        var $dict1 = options;
        for (var $key2 in $dict1) {
            var p = { key: $key2, value: $dict1[$key2] };
            switch (p.key) {
                case 'Validate':
                    break;
                case 'Label':
                    this.subHtml('.Label', p.value.toString());
                    break;
                case 'Value':
                    this.subValue('.Input', p.value.toString());
                    break;
                default:
                    this.subAttr('.Input', p.key, p.value.toString());
                    break;
            }
        }
    },
    
    followFocus: function Nsb_Classes_Truple$followFocus() {
        /// <returns type="Nsb.Classes.Truple"></returns>
        this.element.focusin(function(e) {
            $(e.target).addClass('Focused');
            DomElement.getTruple(e.target).element.addClass('Focused');
        }).focusout(function(e) {
            $(e.target).removeClass('Focused');
            DomElement.getTruple(e.target).element.removeClass('Focused');
        });
        return this;
    },
    
    addSlideTruples: function Nsb_Classes_Truple$addSlideTruples(awp) {
        /// <param name="awp" type="Await">
        /// </param>
        Nsb.Classes.Truple.eachTruple(ss.Delegate.create(this, function(i, domEl) {
            awp.addAw(ss.Delegate.create(this, this.slideInAw), $(domEl));
            return true;
        }));
    },
    
    slideInByNameAw: function Nsb_Classes_Truple$slideInByNameAw(awp, name) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="name" type="String">
        /// </param>
        this.slideInAw(awp, Cluster.truples[name].element);
    }
}


////////////////////////////////////////////////////////////////////////////////
// DomElement

DomElement = function DomElement() {
    /// <field name="resultRx" type="String" static="true">
    /// </field>
    /// <field name="_slideDown" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="_efpCheck" type="Boolean" static="true">
    /// </field>
    /// <field name="_efpRelative" type="Boolean" static="true">
    /// </field>
    /// <field name="_otherFocus" type="Boolean" static="true">
    /// </field>
    /// <field name="_idCnt" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="_idTime" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="element" type="jQueryObject">
    /// </field>
}
DomElement.getTruple = function DomElement$getTruple(el) {
    /// <param name="el" type="jQueryObject">
    /// </param>
    /// <returns type="Nsb.Classes.Truple"></returns>
    if (!(el instanceof jQuery)) {
        el = $(el);
    }
    var t = el.closest('.Truple');
    if (t.length > 0) {
        return t.data('truple');
    }
    return null;
}
DomElement.get_lclId = function DomElement$get_lclId() {
    /// <value type="String"></value>
    return DomElement._idTime + 'x' + (++DomElement._idCnt);
}
DomElement.isValidName = function DomElement$isValidName(name) {
    /// <param name="name" type="String">
    /// </param>
    /// <returns type="Boolean"></returns>
    return !String.isNullOrEmpty(DomElement.cleanName(name));
}
DomElement.isValidNames = function DomElement$isValidNames(name1, name2) {
    /// <param name="name1" type="String">
    /// </param>
    /// <param name="name2" type="String">
    /// </param>
    /// <returns type="Boolean"></returns>
    return DomElement.isValidName(name1) && DomElement.isValidName(name2);
}
DomElement.cleanName = function DomElement$cleanName(name) {
    /// <param name="name" type="String">
    /// </param>
    /// <returns type="String"></returns>
    return (ss.isNullOrUndefined(name)) ? '' : name.trim();
}
DomElement.outerHtml = function DomElement$outerHtml(el) {
    /// <param name="el" type="jQueryObject">
    /// </param>
    /// <returns type="String"></returns>
    var tmp = $('<div/>').insertAfter(el);
    el.appendTo(tmp);
    var html = tmp[0].innerHTML;
    el.insertBefore(tmp);
    tmp.remove();
    return html;
}
DomElement.cancelEvent = function DomElement$cancelEvent(e) {
    /// <param name="e" type="jQueryEvent">
    /// </param>
    if (e == null) {
        return;
    }
    e.stopImmediatePropagation();
    e.stopPropagation();
    e.preventDefault();
}
DomElement.focusElementAw = function DomElement$focusElementAw(awp, el) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="el" type="jQueryObject">
    /// </param>
    el.focus();
    awp.done();
}
DomElement.scrollToPosAw = function DomElement$scrollToPosAw(awp, y) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="y" type="Number" integer="true">
    /// </param>
    var once = false;
    $('body,html,document').animate({ scrollTop: y }, 300, 'swing', function() {
        if (!once) {
            once = true;
            awp.done();
        }
    });
}
DomElement.unselectable = function DomElement$unselectable(el) {
    /// <param name="el" type="jQueryObject">
    /// </param>
    var elem = el[0];
    elem.onselectstart = function() { return false; };
    elem.style.MozUserSelect = 'none';
    elem.style.KhtmlUserSelect = 'none';
    elem.unselectable = 'on';
}
DomElement.windowWidth = function DomElement$windowWidth() {
    /// <returns type="Number" integer="true"></returns>
    return DomElement._fFilterResults((ss.isValue(window.self.innerWidth)) ? window.self.innerWidth : 0, (ss.isValue(document.documentElement)) ? document.documentElement.clientWidth : 0, (ss.isValue(document.body)) ? document.body.clientWidth : 0);
}
DomElement.windowHeight = function DomElement$windowHeight() {
    /// <returns type="Number" integer="true"></returns>
    return DomElement._fFilterResults((ss.isValue(window.self.innerHeight)) ? window.self.innerHeight : 0, (ss.isValue(document.documentElement)) ? document.documentElement.clientHeight : 0, (ss.isValue(document.body)) ? document.body.clientHeight : 0);
}
DomElement.documentWidth = function DomElement$documentWidth() {
    /// <returns type="Number" integer="true"></returns>
    return $(document.documentElement).width();
}
DomElement.documentHeight = function DomElement$documentHeight() {
    /// <returns type="Number" integer="true"></returns>
    return $(document.documentElement).height();
}
DomElement.documentScrollLeft = function DomElement$documentScrollLeft() {
    /// <returns type="Number" integer="true"></returns>
    return DomElement._fFilterResults((ss.isValue(window.self.pageXOffset)) ? window.self.pageXOffset : 0, (ss.isValue(document.documentElement)) ? document.documentElement.scrollLeft : 0, (ss.isValue(document.body)) ? document.body.scrollLeft : 0);
}
DomElement.documentScrollTop = function DomElement$documentScrollTop() {
    /// <returns type="Number" integer="true"></returns>
    return DomElement._fFilterResults((ss.isValue(window.self.pageYOffset)) ? window.self.pageYOffset : 0, (ss.isValue(document.documentElement)) ? document.documentElement.scrollTop : 0, (ss.isValue(document.body)) ? document.body.scrollTop : 0);
}
DomElement._fFilterResults = function DomElement$_fFilterResults(nWin, nDocel, nBody) {
    /// <param name="nWin" type="Number" integer="true">
    /// </param>
    /// <param name="nDocel" type="Number" integer="true">
    /// </param>
    /// <param name="nBody" type="Number" integer="true">
    /// </param>
    /// <returns type="Number" integer="true"></returns>
    var n_result = nWin ? nWin : 0; if (nDocel && (!n_result || (n_result > nDocel))) n_result = nDocel;;
    return nBody && (!n_result || (n_result > nBody)) ? nBody : n_result;;
}
DomElement.elementFromPoint = function DomElement$elementFromPoint(x, y) {
    /// <param name="x" type="Number" integer="true">
    /// </param>
    /// <param name="y" type="Number" integer="true">
    /// </param>
    /// <returns type="Object" domElement="true"></returns>
    if (!document.elementFromPoint) {
        return null;
    }
    if (!DomElement._efpCheck) {
        var sl = 0;
        if ((sl = jQuery(document).scrollTop()) > 0) {
            DomElement._efpRelative = document.elementFromPoint(0, sl + jQuery(window).height() -1) == null;
        }
        else if ((sl = jQuery(document).scrollLeft()) > 0) {
            DomElement._efpRelative = document.elementFromPoint(sl + jQuery(window).width() -1, 0) == null;
        }
        DomElement._efpCheck = (sl > 0);
    }
    if (DomElement._efpRelative) {
        x -= $(window.document).scrollLeft();
        y -= $(window.document).scrollTop();
    }
    return document.elementFromPoint(x, y);
}
DomElement.regMe = function DomElement$regMe(rx) {
    /// <param name="rx" type="String">
    /// </param>
    /// <returns type="RegExp"></returns>
    return eval(rx);
}
DomElement.requireResultAw = function DomElement$requireResultAw(awp, required) {
    /// <param name="awp" type="Await">
    /// </param>
    /// <param name="required" type="Object">
    /// </param>
    if ($.isFunction(required)) {
        var fn = required;
        var ic = fn(awp.get_item('result'));
        if (!ic) {
            awp.abort();
        }
        else {
            awp.done();
        }
        return;
    }
    if (awp.get_item('result') !== required) {
        awp.abort();
    }
    else {
        awp.done();
    }
}
DomElement.notNullOrEmpty = function DomElement$notNullOrEmpty(item) {
    /// <param name="item" type="Object">
    /// </param>
    /// <returns type="Boolean"></returns>
    if (typeof(item) === 'string') {
        return !String.isNullOrEmpty(item);
    }
    if (typeof(item) === 'boolean') {
        return item;
    }
    return ss.isValue(item);
}
DomElement._createOtherFocus = function DomElement$_createOtherFocus() {
    /// <returns type="Boolean"></returns>
    new Await().addDx(function() {
        $("<div id='OtherFocus' tabindex='98989898' style='top:-10000px;left:-10000px'/>").appendTo(document.body);
    }).commit();
    DomElement._otherFocus = !DomElement._otherFocus;
    return true;
}
DomElement.unfocus = function DomElement$unfocus() {
    $('#OtherFocus').focus();
}
DomElement.prototype = {
    
    fromHtml: function DomElement$fromHtml(html) {
        /// <param name="html" type="String">
        /// </param>
        /// <returns type="DomElement"></returns>
        this.element = $(html);
        return this;
    },
    
    append: function DomElement$append(de) {
        /// <param name="de" type="DomElement">
        /// </param>
        /// <returns type="DomElement"></returns>
        if ((de instanceof jQuery)) {
            this.element.append(de);
        }
        else {
            this.element.append(de.element);
        }
        return this;
    },
    
    prepend: function DomElement$prepend(de) {
        /// <param name="de" type="DomElement">
        /// </param>
        /// <returns type="DomElement"></returns>
        if ((de instanceof jQuery)) {
            this.element.prepend(de);
        }
        else {
            this.element.prepend(de.element);
        }
        return this;
    },
    
    appendTo: function DomElement$appendTo(de) {
        /// <param name="de" type="DomElement">
        /// </param>
        /// <returns type="DomElement"></returns>
        if (typeof(de) === 'string') {
            this.element.appendTo(de);
        }
        else if ((de instanceof jQuery)) {
            this.element.appendTo(de);
        }
        else {
            this.element.appendTo(de.element);
        }
        return this;
    },
    
    prependTo: function DomElement$prependTo(de) {
        /// <param name="de" type="DomElement">
        /// </param>
        /// <returns type="DomElement"></returns>
        if ((de instanceof jQuery)) {
            this.element.prependTo(de);
        }
        else {
            this.element.prependTo(de.element);
        }
        return this;
    },
    
    insertAfter: function DomElement$insertAfter(de) {
        /// <param name="de" type="DomElement">
        /// </param>
        /// <returns type="DomElement"></returns>
        if (typeof(de) === 'string') {
            this.element.insertAfter(de);
        }
        else if ((de instanceof jQuery)) {
            this.element.insertAfter(de);
        }
        else {
            this.element.insertAfter(de.element);
        }
        return this;
    },
    
    addClass: function DomElement$addClass(classNames) {
        /// <param name="classNames" type="String">
        /// </param>
        /// <returns type="DomElement"></returns>
        this.element.addClass(classNames);
        return this;
    },
    
    attribute: function DomElement$attribute(name, value) {
        /// <param name="name" type="String">
        /// </param>
        /// <param name="value" type="Object">
        /// </param>
        /// <returns type="DomElement"></returns>
        this.element.attr(name, value.toString());
        return this;
    },
    
    html: function DomElement$html(html) {
        /// <param name="html" type="String">
        /// </param>
        /// <returns type="DomElement"></returns>
        this.element.html(html);
        return this;
    },
    
    select: function DomElement$select(s) {
        /// <param name="s" type="String">
        /// </param>
        /// <returns type="jQueryObject"></returns>
        return $(s, this.element);
    },
    
    element: null,
    
    focusItem: function DomElement$focusItem(selector) {
        /// <param name="selector" type="String">
        /// </param>
        $(selector, this.element).focus();
    },
    
    clearElement: function DomElement$clearElement() {
        if (ss.isValue(this.element)) {
            this.element.empty();
        }
    },
    
    scrollToAw: function DomElement$scrollToAw(awp, el) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="el" type="jQueryObject">
        /// </param>
        el = (el || this.element);
        DomElement.scrollToPosAw(awp, el.offset().top - 2);
    },
    
    scrollInViewAw: function DomElement$scrollInViewAw(awp, el) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="el" type="jQueryObject">
        /// </param>
        if (el == null) {
            awp.done();
            return;
        }
        var ch = DomElement.windowHeight();
        var wb = ch + DomElement.documentScrollTop();
        var eb = el.offset().top + el.outerHeight();
        if (eb > wb) {
            DomElement.scrollToPosAw(awp, eb - ch + 5);
        }
        else {
            awp.done();
        }
    },
    
    removeAw: function DomElement$removeAw(awp) {
        /// <param name="awp" type="Await">
        /// </param>
        this.element.remove();
        awp.done();
    },
    
    fadeOutAw: function DomElement$fadeOutAw(awp, ms) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="ms" type="Number" integer="true">
        /// </param>
        ms = (ms || 250);
        var jar = $('.Jar', this.element);
        jar = (jar.length > 0) ? jar : this.element;
        jar.fadeOut(ms, function() {
            awp.done();
        });
    },
    
    fadeInAw: function DomElement$fadeInAw(awp, ms) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="ms" type="Number" integer="true">
        /// </param>
        ms = (ms || 250);
        var jar = $('.Jar', this.element);
        jar = (jar.length > 0) ? jar : this.element;
        jar.fadeIn(ms, function() {
            awp.done();
        });
    },
    
    slideDownAw: function DomElement$slideDownAw(awp, ms) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="ms" type="Number" integer="true">
        /// </param>
        ms = (ms || 250);
        var jar = $('.Jar', this.element);
        jar = (jar.length > 0) ? jar : this.element;
        jar.slideDown(ms, function() {
            awp.done();
        });
    },
    
    slideUpAw: function DomElement$slideUpAw(awp, ms) {
        /// <param name="awp" type="Await">
        /// </param>
        /// <param name="ms" type="Number" integer="true">
        /// </param>
        ms = (ms || 250);
        var jar = $('.Jar', this.element);
        jar = (jar.length > 0) ? jar : this.element;
        jar.slideUp(ms, function() {
            awp.done();
        });
    },
    
    hideJar: function DomElement$hideJar() {
        var jar = $('.Jar', this.element);
        jar = (jar.length > 0) ? jar : this.element;
        jar.hide();
    },
    
    showJar: function DomElement$showJar() {
        var jar = $('.Jar', this.element);
        jar = (jar.length > 0) ? jar : this.element;
        jar.show();
    },
    
    focus: function DomElement$focus(el) {
        /// <param name="el" type="jQueryObject">
        /// </param>
        el = (el || this.element);
        el.focus();
    },
    
    tabKeyAction: function DomElement$tabKeyAction(fn) {
        /// <param name="fn" type="Function">
        /// </param>
        this.addKeyEvent(9, fn);
    },
    
    escapeKeyAction: function DomElement$escapeKeyAction(fn) {
        /// <param name="fn" type="Function">
        /// </param>
        this.addKeyEvent(27, fn);
    },
    
    returnKeyAction: function DomElement$returnKeyAction(fn) {
        /// <param name="fn" type="Function">
        /// </param>
        this.addKeyEvent(13, fn);
    },
    
    shiftRetKeyAction: function DomElement$shiftRetKeyAction(fn) {
        /// <param name="fn" type="System.Action`1">
        /// </param>
        this.addKeyEvent(13, fn, { shiftKey: true });
    },
    
    addKeyEvent: function DomElement$addKeyEvent(keyCode, fn, qualifiers) {
        /// <param name="keyCode" type="Number" integer="true">
        /// </param>
        /// <param name="fn" type="System.Action`1">
        /// </param>
        /// <param name="qualifiers" type="Object">
        /// </param>
        qualifiers = (qualifiers || {});
        var token = 'KeyToken' + keyCode;
        if (fn == null) {
            this.remKeyEvent(this[token]);
            return;
        }
        var kd = 'keydown.' + DomElement.get_lclId();
        var del = ss.Delegate.create(this, function(e) {
            if (e.which === keyCode && this.objectsHave(qualifiers, e)) {
                DomElement.cancelEvent(e);
                fn(e);
            }
        });
        $(document.documentElement).bind(kd, del);
        this[token] = kd;
    },
    
    objectsHave: function DomElement$objectsHave(o1, o2) {
        /// <param name="o1" type="Object">
        /// </param>
        /// <param name="o2" type="Object">
        /// </param>
        /// <returns type="Boolean"></returns>
        var a = o1;
        var b = o2;
        var $dict1 = a;
        for (var $key2 in $dict1) {
            var p = { key: $key2, value: $dict1[$key2] };
            if (a[p.key] !== b[p.key]) {
                return false;
            }
        }
        return true;
    },
    
    remKeyEvent: function DomElement$remKeyEvent(eventKey) {
        /// <param name="eventKey" type="String">
        /// </param>
        $(document.documentElement).unbind(eventKey);
    }
}


////////////////////////////////////////////////////////////////////////////////
// Constants

Constants = function Constants() {
    /// <field name="undefined" type="Object" static="true">
    /// </field>
    /// <field name="upMark" type="String" static="true">
    /// </field>
    /// <field name="downMark" type="String" static="true">
    /// </field>
    /// <field name="leftMark" type="String" static="true">
    /// </field>
    /// <field name="rightMark" type="String" static="true">
    /// </field>
    /// <field name="zeeAnamae" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="zeeControl" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="zeeButton" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="zeeMeta" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="zeeMenu" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="zeeHider" type="Number" integer="true" static="true">
    /// </field>
    /// <field name="zeeAlert" type="Number" integer="true" static="true">
    /// </field>
}


////////////////////////////////////////////////////////////////////////////////
// Request

Request = function Request() {
    /// <field name="data" type="Object" static="true">
    /// </field>
}
Request.loadNvp = function Request$loadNvp(nvp) {
    /// <param name="nvp" type="String">
    /// </param>
    /// <returns type="Object"></returns>
    var d = {};
    if (nvp.substr(0, 1) === '?') {
        nvp = nvp.substr(1);
    }
    var pairs = nvp.split('&');
    if (pairs.length > 0) {
        var $enum1 = ss.IEnumerator.getEnumerator(pairs);
        while ($enum1.moveNext()) {
            var pair = $enum1.current;
            var p = pair.split('=');
            if (p.length === 2) {
                d[p[0]] = p[1];
            }
        }
    }
    return d;
}


////////////////////////////////////////////////////////////////////////////////
// Inform

Inform = function Inform() {
    /// <field name="tracing" type="Boolean" static="true">
    /// </field>
    /// <field name="passExceptions" type="Boolean" static="true">
    /// </field>
    /// <field name="logActions" type="Boolean" static="true">
    /// </field>
    /// <field name="debugging" type="Boolean" static="true">
    /// </field>
}
Inform.debug = function Inform$debug(msg, v1, v2, v3, v4) {
    /// <param name="msg" type="String">
    /// </param>
    /// <param name="v1" type="Object">
    /// </param>
    /// <param name="v2" type="Object">
    /// </param>
    /// <param name="v3" type="Object">
    /// </param>
    /// <param name="v4" type="Object">
    /// </param>
    if (Inform.debugging) {
        if (window.console) console.warn(String.format('D' + new Date().getTime() + ': ' + msg, v1, v2, v3, v4));
    }
}
Inform.log = function Inform$log(msg, v1, v2, v3, v4) {
    /// <param name="msg" type="String">
    /// </param>
    /// <param name="v1" type="Object">
    /// </param>
    /// <param name="v2" type="Object">
    /// </param>
    /// <param name="v3" type="Object">
    /// </param>
    /// <param name="v4" type="Object">
    /// </param>
    if (window.console) console.log(String.format(msg, v1, v2, v3, v4));
}
Inform.trace = function Inform$trace(msg, v1, v2, v3, v4) {
    /// <param name="msg" type="String">
    /// </param>
    /// <param name="v1" type="Object">
    /// </param>
    /// <param name="v2" type="Object">
    /// </param>
    /// <param name="v3" type="Object">
    /// </param>
    /// <param name="v4" type="Object">
    /// </param>
    if (Inform.tracing) {
        if (window.console) console.log(String.format('Trace: ' + msg, v1, v2, v3, v4));
    }
}
Inform.warn = function Inform$warn(msg, v1, v2, v3, v4) {
    /// <param name="msg" type="String">
    /// </param>
    /// <param name="v1" type="Object">
    /// </param>
    /// <param name="v2" type="Object">
    /// </param>
    /// <param name="v3" type="Object">
    /// </param>
    /// <param name="v4" type="Object">
    /// </param>
    if (window.console) console.warn(String.format(msg, v1, v2, v3, v4));
}
Inform.error = function Inform$error(msg, v1, v2, v3, v4) {
    /// <param name="msg" type="String">
    /// </param>
    /// <param name="v1" type="Object">
    /// </param>
    /// <param name="v2" type="Object">
    /// </param>
    /// <param name="v3" type="Object">
    /// </param>
    /// <param name="v4" type="Object">
    /// </param>
    if (window.console) console.error(String.format(msg, v1, v2, v3, v4));
}
Inform.dump = function Inform$dump(item, name) {
    /// <param name="item" type="Object">
    /// </param>
    /// <param name="name" type="String">
    /// </param>
    Inform.log('Dump of object "{0}"', (ss.isValue(name)) ? name : 'Type=' + Type.getInstanceType(item));
    var s = JSON.stringify(item, function(n, o) {
        return o;
    }, 4);
    if (window.console) console.log(s);
}
Inform.logFn = function Inform$logFn(args) {
    /// <param name="args" type="Object">
    /// </param>
    var n = args.callee.name;
    if (!String.isNullOrEmpty(n)) {
        Inform.log('Doing {0}', n);
    }
}


Type.registerNamespace('Yoshi.Classes');

////////////////////////////////////////////////////////////////////////////////
// PopMenu

PopMenu = function PopMenu() {
    /// <field name="_focuser$3" type="jQueryObject">
    /// </field>
    /// <field name="clickItem" type="jQueryObject">
    /// </field>
    /// <field name="list" type="jQueryObject">
    /// </field>
    /// <field name="_actions$3" type="Object">
    /// </field>
    PopMenu.initializeBase(this);
    this.element = $("<div class='PopMenuWrapper'/>");
    this.list = $("<ul class='PopMenu MenuZee'/>").appendTo(this.element).hide();
    this._focuser$3 = $('<div/>').appendTo(this.element).attr('tabindex', (Formulas.randomOf(10000) + 9999).toString()).hide();
    DomElement.unselectable(this._focuser$3);
}
PopMenu.prototype = {
    _focuser$3: null,
    clickItem: null,
    list: null,
    _actions$3: null,
    
    wrapAround: function PopMenu$wrapAround(el) {
        /// <param name="el" type="jQueryObject">
        /// </param>
        /// <returns type="PopMenu"></returns>
        var display = el.css('display') || 'inline-block';
        if (el.parent().is('.PopMenuWrapper')) {
            el.parent().replaceWith(el);
        }
        el.replaceWith(this.element);
        el.prependTo(this.element);
        var closing = false;
        var menu = null;
        this.element.css({ display: display, position: 'relative' });
        new Await().addDx(ss.Delegate.create(this, function() {
            el.unbind('click.PopMenu').bind('click.PopMenu', ss.Delegate.create(this, function() {
                this.list.css({ position: 'absolute', top: el.position().top + el.outerHeight(), right: -10 });
                if (!closing) {
                    this.list.show();
                    menu = this.list.clone(true, true);
                    menu.css({ top: this.list.offset().top, left: this.list.offset().left, width: this.list.width(), height: this.list.height() });
                    this.list.hide();
                    menu.appendTo('body');
                    menu.show();
                    this._focuser$3.show().focus();
                    this.btnClick();
                }
            }));
            this._focuser$3.css({ position: 'absolute', top: el.outerHeight() + 10, left: el.outerWidth() - 10, width: 1, height: 1 }).focusout(ss.Delegate.create(this, function() {
                closing = true;
                new Await().addDx(ss.Delegate.create(this, function() {
                    this._focuser$3.hide();
                    menu.fadeOut(120, function() {
                        menu.remove();
                        closing = false;
                    });
                    this.menuHide();
                })).commit();
            }));
        })).commit();
        return this;
    },
    
    addList: function PopMenu$addList(actions) {
        /// <param name="actions" type="Object">
        /// </param>
        /// <returns type="PopMenu"></returns>
        if (!ss.isValue(actions) || actions == null || !Object.getKeyCount(actions)) {
            debugger;
            throw new Error('Argument Null');
        }
        this._actions$3 = actions;
        var $dict1 = this._actions$3;
        for (var $key2 in $dict1) {
            var p = { key: $key2, value: $dict1[$key2] };
            if ($.isFunction(p.value)) {
                var item = $("<li class='PopMenuItem' style='clear:both'/>").appendTo(this.list).data('MenuData', p.key).data('MenuFn', p.value).mousedown(ss.Delegate.create(this, function(e) {
                    this.clickItem = $(e.currentTarget);
                    var nd = this.clickItem.data('MenuData');
                    var fn = this.clickItem.data('MenuFn');
                    fn(e, nd);
                    this.itemClick();
                }));
                $('<span/>').appendTo(item).html(p.key);
            }
            else {
                if (String.isNullOrEmpty(p.value)) {
                    $("<div class='Inactive'/>").appendTo(this.list).html(p.key);
                }
                else {
                    var spacer = $("<div class='Spacer' style='clear:both'/>").appendTo(this.list);
                    $("<div style='display:inline-block;width:50%;float:right'><hr></div><div style='float:left'>" + p.value + '</div>').appendTo(spacer);
                }
            }
        }
        return this;
    },
    
    btnClick: function PopMenu$btnClick() {
    },
    
    itemClick: function PopMenu$itemClick() {
    },
    
    menuHide: function PopMenu$menuHide() {
    }
}


////////////////////////////////////////////////////////////////////////////////
// DropMenu

DropMenu = function DropMenu(el, nameList, handler) {
    /// <param name="el" type="jQueryObject">
    /// </param>
    /// <param name="nameList" type="Object">
    /// </param>
    /// <param name="handler" type="Function">
    /// </param>
    /// <field name="fireButton" type="jQueryObject">
    /// </field>
    /// <field name="list" type="jQueryObject">
    /// </field>
    /// <field name="menuWidget" type="jQueryObject">
    /// </field>
    /// <field name="clickItem" type="jQueryObject">
    /// </field>
    if (!ss.isValue(nameList) || el == null || !el.length) {
        debugger;
        throw new Error('Argument Null');
    }
    var priorList = el.prev('.DropMenu');
    if (!priorList.length) {
        if (!Object.getKeyCount(nameList)) {
            return;
        }
        this.menuWidget = $("<div class='DropMenuWidget' style='position:absolute'/>");
        new Await().addDx(ss.Delegate.create(this, function() {
            var p = el.position();
            this.menuWidget.css({ top: p.top, left: p.left + el.outerWidth(), 'margin-top': el.css('margin-top') });
        })).commit();
        this.fireButton = $("<span class='DropMenuFire'/>").appendTo(this.menuWidget).html('&#x25BC;').height(el.outerHeight());
        var focs = $("<span class='DropMenuFocus' style='display:none;color:transparent;background:transparent;position:absolute;right:10px' tabindex='999'/>").appendTo(this.menuWidget).html('&#x25BC;');
        this.list = $("<ul class='DropMenu' style='display:none'/>").appendTo(this.menuWidget);
        this.menuWidget.insertBefore(el);
        this.fireButton.click(ss.Delegate.create(this, function(e) {
            e.preventDefault();
            if (!this.list.is(':visible')) {
                var ht = this.menuWidget.outerHeight();
                focs.css('top', (ht + 4) + 'px').show().focus();
                this.list.css('top', ht + 'px').show();
                this.arrowClick();
            }
        }));
        focs.focusout(ss.Delegate.create(this, function() {
            new Await().addDx(ss.Delegate.create(this, function() {
                this.fireButton.focus();
                focs.hide();
                this.list.fadeOut(120);
                this.menuHide();
            })).commit();
        }));
        DropMenu._unselectable(this.fireButton);
        DropMenu._unselectable(focs);
    }
    else {
        if (!Object.getKeyCount(nameList)) {
            priorList.closest('.DropMenuWidget').remove();
            return;
        }
        this.list = priorList;
        this.list.empty();
    }
    var $dict1 = nameList;
    for (var $key2 in $dict1) {
        var p = { key: $key2, value: $dict1[$key2] };
        var item = $("<li class='DropMenuItem'/>").appendTo(this.list).data('MenuData', p.key).mousedown(ss.Delegate.create(this, function(e) {
            this.clickItem = $(e.currentTarget);
            var nd = this.clickItem.data('MenuData');
            handler(e, nd);
            this.itemClick();
        }));
        $('<span/>').appendTo(item).html(p.value);
    }
}
DropMenu._unselectable = function DropMenu$_unselectable(el) {
    /// <param name="el" type="jQueryObject">
    /// </param>
    var elem = el[0];
    elem.onselectstart = function() { return false; };
    elem.style.MozUserSelect = 'none';
    elem.style.KhtmlUserSelect = 'none';
    elem.unselectable = 'on';
}
DropMenu.listify = function DropMenu$listify(dict, sort, format) {
    /// <param name="dict" type="Object">
    /// </param>
    /// <param name="sort" type="System.Collections.Generic.CompareCallback`1">
    /// </param>
    /// <param name="format" type="System.Action`2">
    /// </param>
    /// <returns type="Object"></returns>
    var mg = [];
    var $enum1 = ss.IEnumerator.getEnumerator(Object.keys(dict));
    while ($enum1.moveNext()) {
        var k = $enum1.current;
        mg.add(dict[k]);
    }
    mg.sort(sort);
    var d = {};
    var $enum2 = ss.IEnumerator.getEnumerator(mg);
    while ($enum2.moveNext()) {
        var o = $enum2.current;
        format(d, o);
    }
    return d;
}
DropMenu.prototype = {
    fireButton: null,
    list: null,
    menuWidget: null,
    clickItem: null,
    
    itemClick: function DropMenu$itemClick() {
    },
    
    arrowClick: function DropMenu$arrowClick() {
    },
    
    menuHide: function DropMenu$menuHide() {
    }
}


Nsb._awaitClassTests.registerClass('Nsb._awaitClassTests');
DynamicCss.registerClass('DynamicCss');
Nsb.Encoder.registerClass('Nsb.Encoder');
Nsb.Storage.registerClass('Nsb.Storage');
Transform.registerClass('Transform');
DomElement.registerClass('DomElement');
Cluster.registerClass('Cluster', DomElement);
Actor.registerClass('Actor', Cluster);
Ask.registerClass('Ask', Actor);
DropTarget.registerClass('DropTarget');
Helpers.registerClass('Helpers');
DDict.registerClass('DDict');
DList.registerClass('DList');
EditHtml.registerClass('EditHtml', Actor);
Exceptions.registerClass('Exceptions');
FileBlobBase.registerClass('FileBlobBase');
Formulas.registerClass('Formulas');
PkgBase.registerClass('PkgBase', FileBlobBase);
CloudMail.registerClass('CloudMail');
Rx.registerClass('Rx');
Strings.registerClass('Strings');
TestInstance.registerClass('TestInstance');
TrueForm.registerClass('TrueForm');
Nsb.Classes.Truple.registerClass('Nsb.Classes.Truple', Actor);
Constants.registerClass('Constants');
Request.registerClass('Request');
Inform.registerClass('Inform');
PopMenu.registerClass('PopMenu', Actor);
DropMenu.registerClass('DropMenu');
Ask.FadeSpeed = 250;
Cluster.truples = {};
Cluster.elements = {};
Cluster._hiderElement$1 = null;
Cluster._hiderCount$1 = 0;
EditHtml._autoErDiv$3 = null;
EditHtml._regExLf$3 = new RegExp('\\r?\\n', 'g');
Exceptions.missingAwaitDoneEr = 'Missing Await Done Callback';
Exceptions.missingDomElement = 'Missing Dom Element';
Exceptions.argumentNull = 'Argument Null';
Exceptions.recordNotExists = "Record doesn't exist";
Exceptions.newRecordExists = 'Record already exists';
Exceptions.invalidName = 'Invalid Name';
Exceptions.userCancelled = 'User Cancelled';
Exceptions.blobLoadError = 'Blob Load Error';
Exceptions.blobSaveError = 'Blob Save Error';
Exceptions.serviceLoginFailure = 'Service Login Failure';
Exceptions.fileIsNewer = 'File is newer';
Exceptions.newUser = 'New User';
Exceptions.invalidPageException = 'Invalid Top Level Page';
Exceptions.sendMailError = 'Send Mail Error';
Exceptions.invalidTestCaseName = 'Invalid Test Case Name';
Exceptions.invalidTestSuiteName = 'Invalid Test Suite Name';
Exceptions.invalidDataOperation = 'Invalid Database Operation';
Exceptions.notImplementedExceptionString = 'Not Implimented';
FileBlobBase.svCnt = 0;
FileBlobBase._modTime = {};
FileBlobBase._xfr = {};
Formulas._idCnt = 0;
Formulas.newIdPrefix = null;
PkgBase.resultRx = 'result';
Rx.hasEndSpace = new RegExp('[^\\s]+\\s+$');
Rx.whiteSpace = new RegExp('\\s+');
Rx.cssFilter = new RegExp('(px|pt|em)$');
Strings._rxSquish = new RegExp('\\s', 'g');
TestInstance.theTest = null;
Nsb.Classes.Truple._tabIndex$3 = 0;
Nsb.Classes.Truple._arrowCodes$3 = [ 37, 40 ];
Nsb.Classes.Truple._blackCodes$3 = [ 8, 8, 46, 90, 96, 111, 186, 222 ];
DomElement.resultRx = 'result';
DomElement._efpCheck = false;
DomElement._efpRelative = false;
DomElement._otherFocus = DomElement._createOtherFocus();
DomElement._idCnt = 0;
DomElement._idTime = new Date().getTime();
Constants.undefined = undefined;
Constants.upMark = '&#x25C3;';
Constants.downMark = '&#x25BC;';
Constants.leftMark = '&#x25C4;';
Constants.rightMark = '&#x25BA;';
Constants.zeeAnamae = 10;
Constants.zeeControl = 50;
Constants.zeeButton = 55;
Constants.zeeMeta = 100;
Constants.zeeMenu = 1000;
Constants.zeeHider = 9999;
Constants.zeeAlert = 10000;
Request.data = Request.loadNvp(window.location.search);
Inform.tracing = false;
Inform.passExceptions = false;
Inform.logActions = false;
Inform.debugging = false;
})();

//! This script was generated using Script# v0.7.4.0
